Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
35271 views
//===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains support for writing dwarf debug info into asm files.9//10//===----------------------------------------------------------------------===//1112#include "DwarfExpression.h"13#include "DwarfCompileUnit.h"14#include "llvm/ADT/APInt.h"15#include "llvm/ADT/SmallBitVector.h"16#include "llvm/BinaryFormat/Dwarf.h"17#include "llvm/CodeGen/Register.h"18#include "llvm/CodeGen/TargetRegisterInfo.h"19#include "llvm/IR/DataLayout.h"20#include "llvm/MC/MCAsmInfo.h"21#include "llvm/Support/ErrorHandling.h"22#include <algorithm>2324using namespace llvm;2526#define DEBUG_TYPE "dwarfdebug"2728void DwarfExpression::emitConstu(uint64_t Value) {29if (Value < 32)30emitOp(dwarf::DW_OP_lit0 + Value);31else if (Value == std::numeric_limits<uint64_t>::max()) {32// Only do this for 64-bit values as the DWARF expression stack uses33// target-address-size values.34emitOp(dwarf::DW_OP_lit0);35emitOp(dwarf::DW_OP_not);36} else {37emitOp(dwarf::DW_OP_constu);38emitUnsigned(Value);39}40}4142void DwarfExpression::addReg(int DwarfReg, const char *Comment) {43assert(DwarfReg >= 0 && "invalid negative dwarf register number");44assert((isUnknownLocation() || isRegisterLocation()) &&45"location description already locked down");46LocationKind = Register;47if (DwarfReg < 32) {48emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);49} else {50emitOp(dwarf::DW_OP_regx, Comment);51emitUnsigned(DwarfReg);52}53}5455void DwarfExpression::addBReg(int DwarfReg, int Offset) {56assert(DwarfReg >= 0 && "invalid negative dwarf register number");57assert(!isRegisterLocation() && "location description already locked down");58if (DwarfReg < 32) {59emitOp(dwarf::DW_OP_breg0 + DwarfReg);60} else {61emitOp(dwarf::DW_OP_bregx);62emitUnsigned(DwarfReg);63}64emitSigned(Offset);65}6667void DwarfExpression::addFBReg(int Offset) {68emitOp(dwarf::DW_OP_fbreg);69emitSigned(Offset);70}7172void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {73if (!SizeInBits)74return;7576const unsigned SizeOfByte = 8;77if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {78emitOp(dwarf::DW_OP_bit_piece);79emitUnsigned(SizeInBits);80emitUnsigned(OffsetInBits);81} else {82emitOp(dwarf::DW_OP_piece);83unsigned ByteSize = SizeInBits / SizeOfByte;84emitUnsigned(ByteSize);85}86this->OffsetInBits += SizeInBits;87}8889void DwarfExpression::addShr(unsigned ShiftBy) {90emitConstu(ShiftBy);91emitOp(dwarf::DW_OP_shr);92}9394void DwarfExpression::addAnd(unsigned Mask) {95emitConstu(Mask);96emitOp(dwarf::DW_OP_and);97}9899bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,100llvm::Register MachineReg,101unsigned MaxSize) {102if (!MachineReg.isPhysical()) {103if (isFrameRegister(TRI, MachineReg)) {104DwarfRegs.push_back(Register::createRegister(-1, nullptr));105return true;106}107return false;108}109110int Reg = TRI.getDwarfRegNum(MachineReg, false);111112// If this is a valid register number, emit it.113if (Reg >= 0) {114DwarfRegs.push_back(Register::createRegister(Reg, nullptr));115return true;116}117118// Walk up the super-register chain until we find a valid number.119// For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.120for (MCPhysReg SR : TRI.superregs(MachineReg)) {121Reg = TRI.getDwarfRegNum(SR, false);122if (Reg >= 0) {123unsigned Idx = TRI.getSubRegIndex(SR, MachineReg);124unsigned Size = TRI.getSubRegIdxSize(Idx);125unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);126DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));127// Use a DW_OP_bit_piece to describe the sub-register.128setSubRegisterPiece(Size, RegOffset);129return true;130}131}132133// Otherwise, attempt to find a covering set of sub-register numbers.134// For example, Q0 on ARM is a composition of D0+D1.135unsigned CurPos = 0;136// The size of the register in bits.137const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);138unsigned RegSize = TRI.getRegSizeInBits(*RC);139// Keep track of the bits in the register we already emitted, so we140// can avoid emitting redundant aliasing subregs. Because this is141// just doing a greedy scan of all subregisters, it is possible that142// this doesn't find a combination of subregisters that fully cover143// the register (even though one may exist).144SmallBitVector Coverage(RegSize, false);145for (MCPhysReg SR : TRI.subregs(MachineReg)) {146unsigned Idx = TRI.getSubRegIndex(MachineReg, SR);147unsigned Size = TRI.getSubRegIdxSize(Idx);148unsigned Offset = TRI.getSubRegIdxOffset(Idx);149Reg = TRI.getDwarfRegNum(SR, false);150if (Reg < 0)151continue;152153// Used to build the intersection between the bits we already154// emitted and the bits covered by this subregister.155SmallBitVector CurSubReg(RegSize, false);156CurSubReg.set(Offset, Offset + Size);157158// If this sub-register has a DWARF number and we haven't covered159// its range, and its range covers the value, emit a DWARF piece for it.160if (Offset < MaxSize && CurSubReg.test(Coverage)) {161// Emit a piece for any gap in the coverage.162if (Offset > CurPos)163DwarfRegs.push_back(Register::createSubRegister(164-1, Offset - CurPos, "no DWARF register encoding"));165if (Offset == 0 && Size >= MaxSize)166DwarfRegs.push_back(Register::createRegister(Reg, "sub-register"));167else168DwarfRegs.push_back(Register::createSubRegister(169Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"));170}171// Mark it as emitted.172Coverage.set(Offset, Offset + Size);173CurPos = Offset + Size;174}175// Failed to find any DWARF encoding.176if (CurPos == 0)177return false;178// Found a partial or complete DWARF encoding.179if (CurPos < RegSize)180DwarfRegs.push_back(Register::createSubRegister(181-1, RegSize - CurPos, "no DWARF register encoding"));182return true;183}184185void DwarfExpression::addStackValue() {186if (DwarfVersion >= 4)187emitOp(dwarf::DW_OP_stack_value);188}189190void DwarfExpression::addSignedConstant(int64_t Value) {191assert(isImplicitLocation() || isUnknownLocation());192LocationKind = Implicit;193emitOp(dwarf::DW_OP_consts);194emitSigned(Value);195}196197void DwarfExpression::addUnsignedConstant(uint64_t Value) {198assert(isImplicitLocation() || isUnknownLocation());199LocationKind = Implicit;200emitConstu(Value);201}202203void DwarfExpression::addUnsignedConstant(const APInt &Value) {204assert(isImplicitLocation() || isUnknownLocation());205LocationKind = Implicit;206207unsigned Size = Value.getBitWidth();208const uint64_t *Data = Value.getRawData();209210// Chop it up into 64-bit pieces, because that's the maximum that211// addUnsignedConstant takes.212unsigned Offset = 0;213while (Offset < Size) {214addUnsignedConstant(*Data++);215if (Offset == 0 && Size <= 64)216break;217addStackValue();218addOpPiece(std::min(Size - Offset, 64u), Offset);219Offset += 64;220}221}222223void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {224assert(isImplicitLocation() || isUnknownLocation());225APInt API = APF.bitcastToAPInt();226int NumBytes = API.getBitWidth() / 8;227if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {228// FIXME: Add support for `long double`.229emitOp(dwarf::DW_OP_implicit_value);230emitUnsigned(NumBytes /*Size of the block in bytes*/);231232// The loop below is emitting the value starting at least significant byte,233// so we need to perform a byte-swap to get the byte order correct in case234// of a big-endian target.235if (AP.getDataLayout().isBigEndian())236API = API.byteSwap();237238for (int i = 0; i < NumBytes; ++i) {239emitData1(API.getZExtValue() & 0xFF);240API = API.lshr(8);241}242243return;244}245LLVM_DEBUG(246dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "247<< API.getBitWidth() << " bits\n");248}249250bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,251DIExpressionCursor &ExprCursor,252llvm::Register MachineReg,253unsigned FragmentOffsetInBits) {254auto Fragment = ExprCursor.getFragmentInfo();255if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {256LocationKind = Unknown;257return false;258}259260bool HasComplexExpression = false;261auto Op = ExprCursor.peek();262if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)263HasComplexExpression = true;264265// If the register can only be described by a complex expression (i.e.,266// multiple subregisters) it doesn't safely compose with another complex267// expression. For example, it is not possible to apply a DW_OP_deref268// operation to multiple DW_OP_pieces, since composite location descriptions269// do not push anything on the DWARF stack.270//271// DW_OP_entry_value operations can only hold a DWARF expression or a272// register location description, so we can't emit a single entry value273// covering a composite location description. In the future we may want to274// emit entry value operations for each register location in the composite275// location, but until that is supported do not emit anything.276if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {277if (IsEmittingEntryValue)278cancelEntryValue();279DwarfRegs.clear();280LocationKind = Unknown;281return false;282}283284// Handle simple register locations. If we are supposed to emit285// a call site parameter expression and if that expression is just a register286// location, emit it with addBReg and offset 0, because we should emit a DWARF287// expression representing a value, rather than a location.288if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||289isEntryValue()) {290auto FragmentInfo = ExprCursor.getFragmentInfo();291unsigned RegSize = 0;292for (auto &Reg : DwarfRegs) {293RegSize += Reg.SubRegSize;294if (Reg.DwarfRegNo >= 0)295addReg(Reg.DwarfRegNo, Reg.Comment);296if (FragmentInfo)297if (RegSize > FragmentInfo->SizeInBits)298// If the register is larger than the current fragment stop299// once the fragment is covered.300break;301addOpPiece(Reg.SubRegSize);302}303304if (isEntryValue()) {305finalizeEntryValue();306307if (!isIndirect() && !isParameterValue() && !HasComplexExpression &&308DwarfVersion >= 4)309emitOp(dwarf::DW_OP_stack_value);310}311312DwarfRegs.clear();313// If we need to mask out a subregister, do it now, unless the next314// operation would emit an OpPiece anyway.315auto NextOp = ExprCursor.peek();316if (SubRegisterSizeInBits && NextOp &&317(NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))318maskSubRegister();319return true;320}321322// Don't emit locations that cannot be expressed without DW_OP_stack_value.323if (DwarfVersion < 4)324if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {325return Op.getOp() == dwarf::DW_OP_stack_value;326})) {327DwarfRegs.clear();328LocationKind = Unknown;329return false;330}331332// TODO: We should not give up here but the following code needs to be changed333// to deal with multiple (sub)registers first.334if (DwarfRegs.size() > 1) {335LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to "336"multi-register usage.\n");337DwarfRegs.clear();338LocationKind = Unknown;339return false;340}341342auto Reg = DwarfRegs[0];343bool FBReg = isFrameRegister(TRI, MachineReg);344int SignedOffset = 0;345assert(!Reg.isSubRegister() && "full register expected");346347// Pattern-match combinations for which more efficient representations exist.348// [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].349if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {350uint64_t Offset = Op->getArg(0);351uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());352if (Offset <= IntMax) {353SignedOffset = Offset;354ExprCursor.take();355}356}357358// [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]359// [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]360// If Reg is a subregister we need to mask it out before subtracting.361if (Op && Op->getOp() == dwarf::DW_OP_constu) {362uint64_t Offset = Op->getArg(0);363uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());364auto N = ExprCursor.peekNext();365if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {366SignedOffset = Offset;367ExprCursor.consume(2);368} else if (N && N->getOp() == dwarf::DW_OP_minus &&369!SubRegisterSizeInBits && Offset <= IntMax + 1) {370SignedOffset = -static_cast<int64_t>(Offset);371ExprCursor.consume(2);372}373}374375if (FBReg)376addFBReg(SignedOffset);377else378addBReg(Reg.DwarfRegNo, SignedOffset);379DwarfRegs.clear();380381// If we need to mask out a subregister, do it now, unless the next382// operation would emit an OpPiece anyway.383auto NextOp = ExprCursor.peek();384if (SubRegisterSizeInBits && NextOp &&385(NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))386maskSubRegister();387388return true;389}390391void DwarfExpression::setEntryValueFlags(const MachineLocation &Loc) {392LocationFlags |= EntryValue;393if (Loc.isIndirect())394LocationFlags |= Indirect;395}396397void DwarfExpression::setLocation(const MachineLocation &Loc,398const DIExpression *DIExpr) {399if (Loc.isIndirect())400setMemoryLocationKind();401402if (DIExpr->isEntryValue())403setEntryValueFlags(Loc);404}405406void DwarfExpression::beginEntryValueExpression(407DIExpressionCursor &ExprCursor) {408auto Op = ExprCursor.take();409(void)Op;410assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value);411assert(!IsEmittingEntryValue && "Already emitting entry value?");412assert(Op->getArg(0) == 1 &&413"Can currently only emit entry values covering a single operation");414415SavedLocationKind = LocationKind;416LocationKind = Register;417LocationFlags |= EntryValue;418IsEmittingEntryValue = true;419enableTemporaryBuffer();420}421422void DwarfExpression::finalizeEntryValue() {423assert(IsEmittingEntryValue && "Entry value not open?");424disableTemporaryBuffer();425426emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));427428// Emit the entry value's size operand.429unsigned Size = getTemporaryBufferSize();430emitUnsigned(Size);431432// Emit the entry value's DWARF block operand.433commitTemporaryBuffer();434435LocationFlags &= ~EntryValue;436LocationKind = SavedLocationKind;437IsEmittingEntryValue = false;438}439440void DwarfExpression::cancelEntryValue() {441assert(IsEmittingEntryValue && "Entry value not open?");442disableTemporaryBuffer();443444// The temporary buffer can't be emptied, so for now just assert that nothing445// has been emitted to it.446assert(getTemporaryBufferSize() == 0 &&447"Began emitting entry value block before cancelling entry value");448449LocationKind = SavedLocationKind;450IsEmittingEntryValue = false;451}452453unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,454dwarf::TypeKind Encoding) {455// Reuse the base_type if we already have one in this CU otherwise we456// create a new one.457unsigned I = 0, E = CU.ExprRefedBaseTypes.size();458for (; I != E; ++I)459if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&460CU.ExprRefedBaseTypes[I].Encoding == Encoding)461break;462463if (I == E)464CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);465return I;466}467468/// Assuming a well-formed expression, match "DW_OP_deref*469/// DW_OP_LLVM_fragment?".470static bool isMemoryLocation(DIExpressionCursor ExprCursor) {471while (ExprCursor) {472auto Op = ExprCursor.take();473switch (Op->getOp()) {474case dwarf::DW_OP_deref:475case dwarf::DW_OP_LLVM_fragment:476break;477default:478return false;479}480}481return true;482}483484void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor) {485addExpression(std::move(ExprCursor),486[](unsigned Idx, DIExpressionCursor &Cursor) -> bool {487llvm_unreachable("unhandled opcode found in expression");488});489}490491bool DwarfExpression::addExpression(492DIExpressionCursor &&ExprCursor,493llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {494// Entry values can currently only cover the initial register location,495// and not any other parts of the following DWARF expression.496assert(!IsEmittingEntryValue && "Can't emit entry value around expression");497498std::optional<DIExpression::ExprOperand> PrevConvertOp;499500while (ExprCursor) {501auto Op = ExprCursor.take();502uint64_t OpNum = Op->getOp();503504if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {505emitOp(OpNum);506continue;507} else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {508addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));509continue;510}511512switch (OpNum) {513case dwarf::DW_OP_LLVM_arg:514if (!InsertArg(Op->getArg(0), ExprCursor)) {515LocationKind = Unknown;516return false;517}518break;519case dwarf::DW_OP_LLVM_fragment: {520unsigned SizeInBits = Op->getArg(1);521unsigned FragmentOffset = Op->getArg(0);522// The fragment offset must have already been adjusted by emitting an523// empty DW_OP_piece / DW_OP_bit_piece before we emitted the base524// location.525assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");526assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");527528// If addMachineReg already emitted DW_OP_piece operations to represent529// a super-register by splicing together sub-registers, subtract the size530// of the pieces that was already emitted.531SizeInBits -= OffsetInBits - FragmentOffset;532533// If addMachineReg requested a DW_OP_bit_piece to stencil out a534// sub-register that is smaller than the current fragment's size, use it.535if (SubRegisterSizeInBits)536SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);537538// Emit a DW_OP_stack_value for implicit location descriptions.539if (isImplicitLocation())540addStackValue();541542// Emit the DW_OP_piece.543addOpPiece(SizeInBits, SubRegisterOffsetInBits);544setSubRegisterPiece(0, 0);545// Reset the location description kind.546LocationKind = Unknown;547return true;548}549case dwarf::DW_OP_LLVM_extract_bits_sext:550case dwarf::DW_OP_LLVM_extract_bits_zext: {551unsigned SizeInBits = Op->getArg(1);552unsigned BitOffset = Op->getArg(0);553554// If we have a memory location then dereference to get the value, though555// we have to make sure we don't dereference any bytes past the end of the556// object.557if (isMemoryLocation()) {558emitOp(dwarf::DW_OP_deref_size);559emitUnsigned(alignTo(BitOffset + SizeInBits, 8) / 8);560}561562// Extract the bits by a shift left (to shift out the bits after what we563// want to extract) followed by shift right (to shift the bits to position564// 0 and also sign/zero extend). These operations are done in the DWARF565// "generic type" whose size is the size of a pointer.566unsigned PtrSizeInBytes = CU.getAsmPrinter()->MAI->getCodePointerSize();567unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);568unsigned RightShift = LeftShift + BitOffset;569if (LeftShift) {570emitOp(dwarf::DW_OP_constu);571emitUnsigned(LeftShift);572emitOp(dwarf::DW_OP_shl);573}574emitOp(dwarf::DW_OP_constu);575emitUnsigned(RightShift);576emitOp(OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra577: dwarf::DW_OP_shr);578579// The value is now at the top of the stack, so set the location to580// implicit so that we get a stack_value at the end.581LocationKind = Implicit;582break;583}584case dwarf::DW_OP_plus_uconst:585assert(!isRegisterLocation());586emitOp(dwarf::DW_OP_plus_uconst);587emitUnsigned(Op->getArg(0));588break;589case dwarf::DW_OP_plus:590case dwarf::DW_OP_minus:591case dwarf::DW_OP_mul:592case dwarf::DW_OP_div:593case dwarf::DW_OP_mod:594case dwarf::DW_OP_or:595case dwarf::DW_OP_and:596case dwarf::DW_OP_xor:597case dwarf::DW_OP_shl:598case dwarf::DW_OP_shr:599case dwarf::DW_OP_shra:600case dwarf::DW_OP_lit0:601case dwarf::DW_OP_not:602case dwarf::DW_OP_dup:603case dwarf::DW_OP_push_object_address:604case dwarf::DW_OP_over:605case dwarf::DW_OP_eq:606case dwarf::DW_OP_ne:607case dwarf::DW_OP_gt:608case dwarf::DW_OP_ge:609case dwarf::DW_OP_lt:610case dwarf::DW_OP_le:611emitOp(OpNum);612break;613case dwarf::DW_OP_deref:614assert(!isRegisterLocation());615if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))616// Turning this into a memory location description makes the deref617// implicit.618LocationKind = Memory;619else620emitOp(dwarf::DW_OP_deref);621break;622case dwarf::DW_OP_constu:623assert(!isRegisterLocation());624emitConstu(Op->getArg(0));625break;626case dwarf::DW_OP_consts:627assert(!isRegisterLocation());628emitOp(dwarf::DW_OP_consts);629emitSigned(Op->getArg(0));630break;631case dwarf::DW_OP_LLVM_convert: {632unsigned BitSize = Op->getArg(0);633dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));634if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {635emitOp(dwarf::DW_OP_convert);636// If targeting a location-list; simply emit the index into the raw637// byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been638// fitted with means to extract it later.639// If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef640// (containing the index and a resolve mechanism during emit) into the641// DIE value list.642emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));643} else {644if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {645if (Encoding == dwarf::DW_ATE_signed)646emitLegacySExt(PrevConvertOp->getArg(0));647else if (Encoding == dwarf::DW_ATE_unsigned)648emitLegacyZExt(PrevConvertOp->getArg(0));649PrevConvertOp = std::nullopt;650} else {651PrevConvertOp = Op;652}653}654break;655}656case dwarf::DW_OP_stack_value:657LocationKind = Implicit;658break;659case dwarf::DW_OP_swap:660assert(!isRegisterLocation());661emitOp(dwarf::DW_OP_swap);662break;663case dwarf::DW_OP_xderef:664assert(!isRegisterLocation());665emitOp(dwarf::DW_OP_xderef);666break;667case dwarf::DW_OP_deref_size:668emitOp(dwarf::DW_OP_deref_size);669emitData1(Op->getArg(0));670break;671case dwarf::DW_OP_LLVM_tag_offset:672TagOffset = Op->getArg(0);673break;674case dwarf::DW_OP_regx:675emitOp(dwarf::DW_OP_regx);676emitUnsigned(Op->getArg(0));677break;678case dwarf::DW_OP_bregx:679emitOp(dwarf::DW_OP_bregx);680emitUnsigned(Op->getArg(0));681emitSigned(Op->getArg(1));682break;683default:684llvm_unreachable("unhandled opcode found in expression");685}686}687688if (isImplicitLocation() && !isParameterValue())689// Turn this into an implicit location description.690addStackValue();691692return true;693}694695/// add masking operations to stencil out a subregister.696void DwarfExpression::maskSubRegister() {697assert(SubRegisterSizeInBits && "no subregister was registered");698if (SubRegisterOffsetInBits > 0)699addShr(SubRegisterOffsetInBits);700uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;701addAnd(Mask);702}703704void DwarfExpression::finalize() {705assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");706// Emit any outstanding DW_OP_piece operations to mask out subregisters.707if (SubRegisterSizeInBits == 0)708return;709// Don't emit a DW_OP_piece for a subregister at offset 0.710if (SubRegisterOffsetInBits == 0)711return;712addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);713}714715void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {716if (!Expr || !Expr->isFragment())717return;718719uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;720assert(FragmentOffset >= OffsetInBits &&721"overlapping or duplicate fragments");722if (FragmentOffset > OffsetInBits)723addOpPiece(FragmentOffset - OffsetInBits);724OffsetInBits = FragmentOffset;725}726727void DwarfExpression::emitLegacySExt(unsigned FromBits) {728// (((X >> (FromBits - 1)) * (~0)) << FromBits) | X729emitOp(dwarf::DW_OP_dup);730emitOp(dwarf::DW_OP_constu);731emitUnsigned(FromBits - 1);732emitOp(dwarf::DW_OP_shr);733emitOp(dwarf::DW_OP_lit0);734emitOp(dwarf::DW_OP_not);735emitOp(dwarf::DW_OP_mul);736emitOp(dwarf::DW_OP_constu);737emitUnsigned(FromBits);738emitOp(dwarf::DW_OP_shl);739emitOp(dwarf::DW_OP_or);740}741742void DwarfExpression::emitLegacyZExt(unsigned FromBits) {743// Heuristic to decide the most efficient encoding.744// A ULEB can encode 7 1-bits per byte.745if (FromBits / 7 < 1+1+1+1+1) {746// (X & (1 << FromBits - 1))747emitOp(dwarf::DW_OP_constu);748emitUnsigned((1ULL << FromBits) - 1);749} else {750// Note that the DWARF 4 stack consists of pointer-sized elements,751// so technically it doesn't make sense to shift left more than 64752// bits. We leave that for the consumer to decide though. LLDB for753// example uses APInt for the stack elements and can still deal754// with this.755emitOp(dwarf::DW_OP_lit1);756emitOp(dwarf::DW_OP_constu);757emitUnsigned(FromBits);758emitOp(dwarf::DW_OP_shl);759emitOp(dwarf::DW_OP_lit1);760emitOp(dwarf::DW_OP_minus);761}762emitOp(dwarf::DW_OP_and);763}764765void DwarfExpression::addWasmLocation(unsigned Index, uint64_t Offset) {766emitOp(dwarf::DW_OP_WASM_location);767emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index);768emitUnsigned(Offset);769if (Index == 4 /*TI_LOCAL_INDIRECT*/) {770assert(LocationKind == Unknown);771LocationKind = Memory;772} else {773assert(LocationKind == Implicit || LocationKind == Unknown);774LocationKind = Implicit;775}776}777778779