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 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 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 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 680b57cec5SDimitry Andric void DwarfExpression::addFBReg(int Offset) { 690b57cec5SDimitry Andric emitOp(dwarf::DW_OP_fbreg); 700b57cec5SDimitry Andric emitSigned(Offset); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 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 900b57cec5SDimitry Andric void DwarfExpression::addShr(unsigned ShiftBy) { 910b57cec5SDimitry Andric emitConstu(ShiftBy); 920b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shr); 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric void DwarfExpression::addAnd(unsigned Mask) { 960b57cec5SDimitry Andric emitConstu(Mask); 970b57cec5SDimitry Andric emitOp(dwarf::DW_OP_and); 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 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 1860b57cec5SDimitry Andric void DwarfExpression::addStackValue() { 1870b57cec5SDimitry Andric if (DwarfVersion >= 4) 1880b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value); 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 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 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 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 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 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 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 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 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 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 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 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?". 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 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 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. 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 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 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 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 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 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