12cab237bSDimitry Andric //===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
239d628a0SDimitry Andric //
339d628a0SDimitry Andric // The LLVM Compiler Infrastructure
439d628a0SDimitry Andric //
539d628a0SDimitry Andric // This file is distributed under the University of Illinois Open Source
639d628a0SDimitry Andric // License. See LICENSE.TXT for details.
739d628a0SDimitry Andric //
839d628a0SDimitry Andric //===----------------------------------------------------------------------===//
939d628a0SDimitry Andric //
1039d628a0SDimitry Andric // This file contains support for writing dwarf debug info into asm files.
1139d628a0SDimitry Andric //
1239d628a0SDimitry Andric //===----------------------------------------------------------------------===//
1339d628a0SDimitry Andric
1439d628a0SDimitry Andric #include "DwarfExpression.h"
152cab237bSDimitry Andric #include "llvm/ADT/APInt.h"
1639d628a0SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
17db17bf38SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
192cab237bSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
202cab237bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
212cab237bSDimitry Andric #include <algorithm>
222cab237bSDimitry Andric #include <cassert>
232cab237bSDimitry Andric #include <cstdint>
2439d628a0SDimitry Andric
2539d628a0SDimitry Andric using namespace llvm;
2639d628a0SDimitry Andric
emitConstu(uint64_t Value)27*b5893f02SDimitry Andric void DwarfExpression::emitConstu(uint64_t Value) {
28*b5893f02SDimitry Andric if (Value < 32)
29*b5893f02SDimitry Andric emitOp(dwarf::DW_OP_lit0 + Value);
30*b5893f02SDimitry Andric else if (Value == std::numeric_limits<uint64_t>::max()) {
31*b5893f02SDimitry Andric // Only do this for 64-bit values as the DWARF expression stack uses
32*b5893f02SDimitry Andric // target-address-size values.
33*b5893f02SDimitry Andric emitOp(dwarf::DW_OP_lit0);
34*b5893f02SDimitry Andric emitOp(dwarf::DW_OP_not);
35*b5893f02SDimitry Andric } else {
36*b5893f02SDimitry Andric emitOp(dwarf::DW_OP_constu);
37*b5893f02SDimitry Andric emitUnsigned(Value);
38*b5893f02SDimitry Andric }
39*b5893f02SDimitry Andric }
40*b5893f02SDimitry Andric
addReg(int DwarfReg,const char * Comment)417a7e6055SDimitry Andric void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
4239d628a0SDimitry Andric assert(DwarfReg >= 0 && "invalid negative dwarf register number");
436bc11b14SDimitry Andric assert((LocationKind == Unknown || LocationKind == Register) &&
446bc11b14SDimitry Andric "location description already locked down");
456bc11b14SDimitry Andric LocationKind = Register;
4639d628a0SDimitry Andric if (DwarfReg < 32) {
477a7e6055SDimitry Andric emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
4839d628a0SDimitry Andric } else {
497a7e6055SDimitry Andric emitOp(dwarf::DW_OP_regx, Comment);
507a7e6055SDimitry Andric emitUnsigned(DwarfReg);
5139d628a0SDimitry Andric }
5239d628a0SDimitry Andric }
5339d628a0SDimitry Andric
addBReg(int DwarfReg,int Offset)547a7e6055SDimitry Andric void DwarfExpression::addBReg(int DwarfReg, int Offset) {
5539d628a0SDimitry Andric assert(DwarfReg >= 0 && "invalid negative dwarf register number");
566bc11b14SDimitry Andric assert(LocationKind != Register && "location description already locked down");
5739d628a0SDimitry Andric if (DwarfReg < 32) {
587a7e6055SDimitry Andric emitOp(dwarf::DW_OP_breg0 + DwarfReg);
5939d628a0SDimitry Andric } else {
607a7e6055SDimitry Andric emitOp(dwarf::DW_OP_bregx);
617a7e6055SDimitry Andric emitUnsigned(DwarfReg);
6239d628a0SDimitry Andric }
637a7e6055SDimitry Andric emitSigned(Offset);
6439d628a0SDimitry Andric }
6539d628a0SDimitry Andric
addFBReg(int Offset)667a7e6055SDimitry Andric void DwarfExpression::addFBReg(int Offset) {
677a7e6055SDimitry Andric emitOp(dwarf::DW_OP_fbreg);
687a7e6055SDimitry Andric emitSigned(Offset);
697a7e6055SDimitry Andric }
707a7e6055SDimitry Andric
addOpPiece(unsigned SizeInBits,unsigned OffsetInBits)717a7e6055SDimitry Andric void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
72d88c1a5aSDimitry Andric if (!SizeInBits)
73d88c1a5aSDimitry Andric return;
74d88c1a5aSDimitry Andric
7539d628a0SDimitry Andric const unsigned SizeOfByte = 8;
7639d628a0SDimitry Andric if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
777a7e6055SDimitry Andric emitOp(dwarf::DW_OP_bit_piece);
787a7e6055SDimitry Andric emitUnsigned(SizeInBits);
797a7e6055SDimitry Andric emitUnsigned(OffsetInBits);
8039d628a0SDimitry Andric } else {
817a7e6055SDimitry Andric emitOp(dwarf::DW_OP_piece);
8239d628a0SDimitry Andric unsigned ByteSize = SizeInBits / SizeOfByte;
837a7e6055SDimitry Andric emitUnsigned(ByteSize);
8439d628a0SDimitry Andric }
85d88c1a5aSDimitry Andric this->OffsetInBits += SizeInBits;
8639d628a0SDimitry Andric }
8739d628a0SDimitry Andric
addShr(unsigned ShiftBy)887a7e6055SDimitry Andric void DwarfExpression::addShr(unsigned ShiftBy) {
89*b5893f02SDimitry Andric emitConstu(ShiftBy);
907a7e6055SDimitry Andric emitOp(dwarf::DW_OP_shr);
9139d628a0SDimitry Andric }
9239d628a0SDimitry Andric
addAnd(unsigned Mask)937a7e6055SDimitry Andric void DwarfExpression::addAnd(unsigned Mask) {
94*b5893f02SDimitry Andric emitConstu(Mask);
957a7e6055SDimitry Andric emitOp(dwarf::DW_OP_and);
9639d628a0SDimitry Andric }
97ff0cc061SDimitry Andric
addMachineReg(const TargetRegisterInfo & TRI,unsigned MachineReg,unsigned MaxSize)987a7e6055SDimitry Andric bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
99d88c1a5aSDimitry Andric unsigned MachineReg, unsigned MaxSize) {
1007a7e6055SDimitry Andric if (!TRI.isPhysicalRegister(MachineReg)) {
1017a7e6055SDimitry Andric if (isFrameRegister(TRI, MachineReg)) {
1027a7e6055SDimitry Andric DwarfRegs.push_back({-1, 0, nullptr});
1037a7e6055SDimitry Andric return true;
1047a7e6055SDimitry Andric }
105ff0cc061SDimitry Andric return false;
1067a7e6055SDimitry Andric }
107ff0cc061SDimitry Andric
108ff0cc061SDimitry Andric int Reg = TRI.getDwarfRegNum(MachineReg, false);
10939d628a0SDimitry Andric
11039d628a0SDimitry Andric // If this is a valid register number, emit it.
11139d628a0SDimitry Andric if (Reg >= 0) {
1127a7e6055SDimitry Andric DwarfRegs.push_back({Reg, 0, nullptr});
11339d628a0SDimitry Andric return true;
11439d628a0SDimitry Andric }
11539d628a0SDimitry Andric
11639d628a0SDimitry Andric // Walk up the super-register chain until we find a valid number.
117d88c1a5aSDimitry Andric // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
118ff0cc061SDimitry Andric for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
119ff0cc061SDimitry Andric Reg = TRI.getDwarfRegNum(*SR, false);
12039d628a0SDimitry Andric if (Reg >= 0) {
121ff0cc061SDimitry Andric unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
122ff0cc061SDimitry Andric unsigned Size = TRI.getSubRegIdxSize(Idx);
123ff0cc061SDimitry Andric unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
1247a7e6055SDimitry Andric DwarfRegs.push_back({Reg, 0, "super-register"});
125d88c1a5aSDimitry Andric // Use a DW_OP_bit_piece to describe the sub-register.
126d88c1a5aSDimitry Andric setSubRegisterPiece(Size, RegOffset);
12739d628a0SDimitry Andric return true;
12839d628a0SDimitry Andric }
12939d628a0SDimitry Andric }
13039d628a0SDimitry Andric
13139d628a0SDimitry Andric // Otherwise, attempt to find a covering set of sub-register numbers.
13239d628a0SDimitry Andric // For example, Q0 on ARM is a composition of D0+D1.
133d88c1a5aSDimitry Andric unsigned CurPos = 0;
13451690af2SDimitry Andric // The size of the register in bits.
13551690af2SDimitry Andric const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
13651690af2SDimitry Andric unsigned RegSize = TRI.getRegSizeInBits(*RC);
13739d628a0SDimitry Andric // Keep track of the bits in the register we already emitted, so we
1384ba319b5SDimitry Andric // can avoid emitting redundant aliasing subregs. Because this is
1394ba319b5SDimitry Andric // just doing a greedy scan of all subregisters, it is possible that
1404ba319b5SDimitry Andric // this doesn't find a combination of subregisters that fully cover
1414ba319b5SDimitry Andric // the register (even though one may exist).
14239d628a0SDimitry Andric SmallBitVector Coverage(RegSize, false);
143ff0cc061SDimitry Andric for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
144ff0cc061SDimitry Andric unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
145ff0cc061SDimitry Andric unsigned Size = TRI.getSubRegIdxSize(Idx);
146ff0cc061SDimitry Andric unsigned Offset = TRI.getSubRegIdxOffset(Idx);
147ff0cc061SDimitry Andric Reg = TRI.getDwarfRegNum(*SR, false);
1482cab237bSDimitry Andric if (Reg < 0)
1492cab237bSDimitry Andric continue;
15039d628a0SDimitry Andric
15139d628a0SDimitry Andric // Intersection between the bits we already emitted and the bits
15239d628a0SDimitry Andric // covered by this subregister.
153d4419f6fSDimitry Andric SmallBitVector CurSubReg(RegSize, false);
154d4419f6fSDimitry Andric CurSubReg.set(Offset, Offset + Size);
15539d628a0SDimitry Andric
15639d628a0SDimitry Andric // If this sub-register has a DWARF number and we haven't covered
15739d628a0SDimitry Andric // its range, emit a DWARF piece for it.
1582cab237bSDimitry Andric if (CurSubReg.test(Coverage)) {
1597a7e6055SDimitry Andric // Emit a piece for any gap in the coverage.
1607a7e6055SDimitry Andric if (Offset > CurPos)
1614ba319b5SDimitry Andric DwarfRegs.push_back({-1, Offset - CurPos, "no DWARF register encoding"});
1627a7e6055SDimitry Andric DwarfRegs.push_back(
1637a7e6055SDimitry Andric {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
164d88c1a5aSDimitry Andric if (Offset >= MaxSize)
165d88c1a5aSDimitry Andric break;
16639d628a0SDimitry Andric
16739d628a0SDimitry Andric // Mark it as emitted.
16839d628a0SDimitry Andric Coverage.set(Offset, Offset + Size);
1697a7e6055SDimitry Andric CurPos = Offset + Size;
17039d628a0SDimitry Andric }
17139d628a0SDimitry Andric }
1724ba319b5SDimitry Andric // Failed to find any DWARF encoding.
1734ba319b5SDimitry Andric if (CurPos == 0)
1744ba319b5SDimitry Andric return false;
1754ba319b5SDimitry Andric // Found a partial or complete DWARF encoding.
1764ba319b5SDimitry Andric if (CurPos < RegSize)
1774ba319b5SDimitry Andric DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"});
1784ba319b5SDimitry Andric return true;
17939d628a0SDimitry Andric }
18039d628a0SDimitry Andric
addStackValue()1817a7e6055SDimitry Andric void DwarfExpression::addStackValue() {
1828f0fd8f6SDimitry Andric if (DwarfVersion >= 4)
1837a7e6055SDimitry Andric emitOp(dwarf::DW_OP_stack_value);
18439d628a0SDimitry Andric }
18539d628a0SDimitry Andric
addSignedConstant(int64_t Value)1867a7e6055SDimitry Andric void DwarfExpression::addSignedConstant(int64_t Value) {
1876bc11b14SDimitry Andric assert(LocationKind == Implicit || LocationKind == Unknown);
1886bc11b14SDimitry Andric LocationKind = Implicit;
1897a7e6055SDimitry Andric emitOp(dwarf::DW_OP_consts);
1907a7e6055SDimitry Andric emitSigned(Value);
1913ca95b02SDimitry Andric }
1923ca95b02SDimitry Andric
addUnsignedConstant(uint64_t Value)1937a7e6055SDimitry Andric void DwarfExpression::addUnsignedConstant(uint64_t Value) {
1946bc11b14SDimitry Andric assert(LocationKind == Implicit || LocationKind == Unknown);
1956bc11b14SDimitry Andric LocationKind = Implicit;
196*b5893f02SDimitry Andric emitConstu(Value);
1973ca95b02SDimitry Andric }
1983ca95b02SDimitry Andric
addUnsignedConstant(const APInt & Value)1997a7e6055SDimitry Andric void DwarfExpression::addUnsignedConstant(const APInt &Value) {
2006bc11b14SDimitry Andric assert(LocationKind == Implicit || LocationKind == Unknown);
2016bc11b14SDimitry Andric LocationKind = Implicit;
2026bc11b14SDimitry Andric
2033ca95b02SDimitry Andric unsigned Size = Value.getBitWidth();
2043ca95b02SDimitry Andric const uint64_t *Data = Value.getRawData();
2053ca95b02SDimitry Andric
2063ca95b02SDimitry Andric // Chop it up into 64-bit pieces, because that's the maximum that
2077a7e6055SDimitry Andric // addUnsignedConstant takes.
2083ca95b02SDimitry Andric unsigned Offset = 0;
2093ca95b02SDimitry Andric while (Offset < Size) {
2107a7e6055SDimitry Andric addUnsignedConstant(*Data++);
2113ca95b02SDimitry Andric if (Offset == 0 && Size <= 64)
2123ca95b02SDimitry Andric break;
2136bc11b14SDimitry Andric addStackValue();
2147a7e6055SDimitry Andric addOpPiece(std::min(Size - Offset, 64u), Offset);
2153ca95b02SDimitry Andric Offset += 64;
2163ca95b02SDimitry Andric }
21739d628a0SDimitry Andric }
21839d628a0SDimitry Andric
addMachineRegExpression(const TargetRegisterInfo & TRI,DIExpressionCursor & ExprCursor,unsigned MachineReg,unsigned FragmentOffsetInBits)2197a7e6055SDimitry Andric bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
220d88c1a5aSDimitry Andric DIExpressionCursor &ExprCursor,
22139d628a0SDimitry Andric unsigned MachineReg,
222d88c1a5aSDimitry Andric unsigned FragmentOffsetInBits) {
2237a7e6055SDimitry Andric auto Fragment = ExprCursor.getFragmentInfo();
22451690af2SDimitry Andric if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
22551690af2SDimitry Andric LocationKind = Unknown;
2267a7e6055SDimitry Andric return false;
22751690af2SDimitry Andric }
228ff0cc061SDimitry Andric
2297a7e6055SDimitry Andric bool HasComplexExpression = false;
230d88c1a5aSDimitry Andric auto Op = ExprCursor.peek();
2317a7e6055SDimitry Andric if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
2327a7e6055SDimitry Andric HasComplexExpression = true;
2337a7e6055SDimitry Andric
2347a7e6055SDimitry Andric // If the register can only be described by a complex expression (i.e.,
2357a7e6055SDimitry Andric // multiple subregisters) it doesn't safely compose with another complex
2367a7e6055SDimitry Andric // expression. For example, it is not possible to apply a DW_OP_deref
2377a7e6055SDimitry Andric // operation to multiple DW_OP_pieces.
2387a7e6055SDimitry Andric if (HasComplexExpression && DwarfRegs.size() > 1) {
2397a7e6055SDimitry Andric DwarfRegs.clear();
24051690af2SDimitry Andric LocationKind = Unknown;
2417a7e6055SDimitry Andric return false;
2427a7e6055SDimitry Andric }
2437a7e6055SDimitry Andric
2447a7e6055SDimitry Andric // Handle simple register locations.
2456bc11b14SDimitry Andric if (LocationKind != Memory && !HasComplexExpression) {
2467a7e6055SDimitry Andric for (auto &Reg : DwarfRegs) {
2477a7e6055SDimitry Andric if (Reg.DwarfRegNo >= 0)
2487a7e6055SDimitry Andric addReg(Reg.DwarfRegNo, Reg.Comment);
2497a7e6055SDimitry Andric addOpPiece(Reg.Size);
2507a7e6055SDimitry Andric }
2517a7e6055SDimitry Andric DwarfRegs.clear();
2527a7e6055SDimitry Andric return true;
2537a7e6055SDimitry Andric }
2547a7e6055SDimitry Andric
2556bc11b14SDimitry Andric // Don't emit locations that cannot be expressed without DW_OP_stack_value.
2566bc11b14SDimitry Andric if (DwarfVersion < 4)
257*b5893f02SDimitry Andric if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
2586bc11b14SDimitry Andric return Op.getOp() == dwarf::DW_OP_stack_value;
2596bc11b14SDimitry Andric })) {
2606bc11b14SDimitry Andric DwarfRegs.clear();
26151690af2SDimitry Andric LocationKind = Unknown;
2626bc11b14SDimitry Andric return false;
2636bc11b14SDimitry Andric }
2646bc11b14SDimitry Andric
2657a7e6055SDimitry Andric assert(DwarfRegs.size() == 1);
2667a7e6055SDimitry Andric auto Reg = DwarfRegs[0];
2677a7e6055SDimitry Andric bool FBReg = isFrameRegister(TRI, MachineReg);
2686bc11b14SDimitry Andric int SignedOffset = 0;
2697a7e6055SDimitry Andric assert(Reg.Size == 0 && "subregister has same size as superregister");
2707a7e6055SDimitry Andric
2717a7e6055SDimitry Andric // Pattern-match combinations for which more efficient representations exist.
27224d58133SDimitry Andric // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
27324d58133SDimitry Andric if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
27424d58133SDimitry Andric SignedOffset = Op->getArg(0);
2756bc11b14SDimitry Andric ExprCursor.take();
2766bc11b14SDimitry Andric }
27724d58133SDimitry Andric
27824d58133SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
27924d58133SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
28024d58133SDimitry Andric // If Reg is a subregister we need to mask it out before subtracting.
28124d58133SDimitry Andric if (Op && Op->getOp() == dwarf::DW_OP_constu) {
28224d58133SDimitry Andric auto N = ExprCursor.peekNext();
28324d58133SDimitry Andric if (N && (N->getOp() == dwarf::DW_OP_plus ||
28424d58133SDimitry Andric (N->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
28524d58133SDimitry Andric int Offset = Op->getArg(0);
28624d58133SDimitry Andric SignedOffset = (N->getOp() == dwarf::DW_OP_minus) ? -Offset : Offset;
28724d58133SDimitry Andric ExprCursor.consume(2);
28824d58133SDimitry Andric }
28924d58133SDimitry Andric }
29024d58133SDimitry Andric
2917a7e6055SDimitry Andric if (FBReg)
2927a7e6055SDimitry Andric addFBReg(SignedOffset);
2937a7e6055SDimitry Andric else
2947a7e6055SDimitry Andric addBReg(Reg.DwarfRegNo, SignedOffset);
2957a7e6055SDimitry Andric DwarfRegs.clear();
2967a7e6055SDimitry Andric return true;
297ff0cc061SDimitry Andric }
29839d628a0SDimitry Andric
2996bc11b14SDimitry Andric /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
isMemoryLocation(DIExpressionCursor ExprCursor)3006bc11b14SDimitry Andric static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
3016bc11b14SDimitry Andric while (ExprCursor) {
3026bc11b14SDimitry Andric auto Op = ExprCursor.take();
3036bc11b14SDimitry Andric switch (Op->getOp()) {
3046bc11b14SDimitry Andric case dwarf::DW_OP_deref:
3056bc11b14SDimitry Andric case dwarf::DW_OP_LLVM_fragment:
3066bc11b14SDimitry Andric break;
3076bc11b14SDimitry Andric default:
3086bc11b14SDimitry Andric return false;
3096bc11b14SDimitry Andric }
3106bc11b14SDimitry Andric }
3116bc11b14SDimitry Andric return true;
3126bc11b14SDimitry Andric }
3136bc11b14SDimitry Andric
addExpression(DIExpressionCursor && ExprCursor,unsigned FragmentOffsetInBits)3147a7e6055SDimitry Andric void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
315d88c1a5aSDimitry Andric unsigned FragmentOffsetInBits) {
3167a7e6055SDimitry Andric // If we need to mask out a subregister, do it now, unless the next
3177a7e6055SDimitry Andric // operation would emit an OpPiece anyway.
3186bc11b14SDimitry Andric auto N = ExprCursor.peek();
3196bc11b14SDimitry Andric if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
3207a7e6055SDimitry Andric maskSubRegister();
3217a7e6055SDimitry Andric
3226bc11b14SDimitry Andric while (ExprCursor) {
3236bc11b14SDimitry Andric auto Op = ExprCursor.take();
324d88c1a5aSDimitry Andric switch (Op->getOp()) {
325d88c1a5aSDimitry Andric case dwarf::DW_OP_LLVM_fragment: {
326d88c1a5aSDimitry Andric unsigned SizeInBits = Op->getArg(1);
327d88c1a5aSDimitry Andric unsigned FragmentOffset = Op->getArg(0);
328d88c1a5aSDimitry Andric // The fragment offset must have already been adjusted by emitting an
329d88c1a5aSDimitry Andric // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
330d88c1a5aSDimitry Andric // location.
331d88c1a5aSDimitry Andric assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
33239d628a0SDimitry Andric
3336bc11b14SDimitry Andric // If addMachineReg already emitted DW_OP_piece operations to represent
334d88c1a5aSDimitry Andric // a super-register by splicing together sub-registers, subtract the size
335d88c1a5aSDimitry Andric // of the pieces that was already emitted.
336d88c1a5aSDimitry Andric SizeInBits -= OffsetInBits - FragmentOffset;
33739d628a0SDimitry Andric
3386bc11b14SDimitry Andric // If addMachineReg requested a DW_OP_bit_piece to stencil out a
339d88c1a5aSDimitry Andric // sub-register that is smaller than the current fragment's size, use it.
340d88c1a5aSDimitry Andric if (SubRegisterSizeInBits)
341d88c1a5aSDimitry Andric SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
342d88c1a5aSDimitry Andric
3436bc11b14SDimitry Andric // Emit a DW_OP_stack_value for implicit location descriptions.
3446bc11b14SDimitry Andric if (LocationKind == Implicit)
3456bc11b14SDimitry Andric addStackValue();
3466bc11b14SDimitry Andric
3476bc11b14SDimitry Andric // Emit the DW_OP_piece.
3487a7e6055SDimitry Andric addOpPiece(SizeInBits, SubRegisterOffsetInBits);
349d88c1a5aSDimitry Andric setSubRegisterPiece(0, 0);
3506bc11b14SDimitry Andric // Reset the location description kind.
3516bc11b14SDimitry Andric LocationKind = Unknown;
3526bc11b14SDimitry Andric return;
35339d628a0SDimitry Andric }
35424d58133SDimitry Andric case dwarf::DW_OP_plus_uconst:
3556bc11b14SDimitry Andric assert(LocationKind != Register);
3567a7e6055SDimitry Andric emitOp(dwarf::DW_OP_plus_uconst);
3577a7e6055SDimitry Andric emitUnsigned(Op->getArg(0));
35839d628a0SDimitry Andric break;
35924d58133SDimitry Andric case dwarf::DW_OP_plus:
3607d523365SDimitry Andric case dwarf::DW_OP_minus:
3612cab237bSDimitry Andric case dwarf::DW_OP_mul:
3624ba319b5SDimitry Andric case dwarf::DW_OP_div:
3634ba319b5SDimitry Andric case dwarf::DW_OP_mod:
3644ba319b5SDimitry Andric case dwarf::DW_OP_or:
3654ba319b5SDimitry Andric case dwarf::DW_OP_and:
3664ba319b5SDimitry Andric case dwarf::DW_OP_xor:
3674ba319b5SDimitry Andric case dwarf::DW_OP_shl:
3684ba319b5SDimitry Andric case dwarf::DW_OP_shr:
3694ba319b5SDimitry Andric case dwarf::DW_OP_shra:
3704ba319b5SDimitry Andric case dwarf::DW_OP_lit0:
3714ba319b5SDimitry Andric case dwarf::DW_OP_not:
3724ba319b5SDimitry Andric case dwarf::DW_OP_dup:
37324d58133SDimitry Andric emitOp(Op->getOp());
3747d523365SDimitry Andric break;
3752cab237bSDimitry Andric case dwarf::DW_OP_deref:
3766bc11b14SDimitry Andric assert(LocationKind != Register);
3774ba319b5SDimitry Andric if (LocationKind != Memory && ::isMemoryLocation(ExprCursor))
3786bc11b14SDimitry Andric // Turning this into a memory location description makes the deref
3796bc11b14SDimitry Andric // implicit.
3806bc11b14SDimitry Andric LocationKind = Memory;
3816bc11b14SDimitry Andric else
3827a7e6055SDimitry Andric emitOp(dwarf::DW_OP_deref);
38339d628a0SDimitry Andric break;
384d88c1a5aSDimitry Andric case dwarf::DW_OP_constu:
3856bc11b14SDimitry Andric assert(LocationKind != Register);
386*b5893f02SDimitry Andric emitConstu(Op->getArg(0));
387d88c1a5aSDimitry Andric break;
388d88c1a5aSDimitry Andric case dwarf::DW_OP_stack_value:
3896bc11b14SDimitry Andric LocationKind = Implicit;
3907a7e6055SDimitry Andric break;
3917a7e6055SDimitry Andric case dwarf::DW_OP_swap:
3926bc11b14SDimitry Andric assert(LocationKind != Register);
3937a7e6055SDimitry Andric emitOp(dwarf::DW_OP_swap);
3947a7e6055SDimitry Andric break;
3957a7e6055SDimitry Andric case dwarf::DW_OP_xderef:
3966bc11b14SDimitry Andric assert(LocationKind != Register);
3977a7e6055SDimitry Andric emitOp(dwarf::DW_OP_xderef);
398d88c1a5aSDimitry Andric break;
39939d628a0SDimitry Andric default:
400ff0cc061SDimitry Andric llvm_unreachable("unhandled opcode found in expression");
40139d628a0SDimitry Andric }
40239d628a0SDimitry Andric }
4036bc11b14SDimitry Andric
4046bc11b14SDimitry Andric if (LocationKind == Implicit)
4056bc11b14SDimitry Andric // Turn this into an implicit location description.
4066bc11b14SDimitry Andric addStackValue();
40739d628a0SDimitry Andric }
408d88c1a5aSDimitry Andric
4097a7e6055SDimitry Andric /// add masking operations to stencil out a subregister.
maskSubRegister()4107a7e6055SDimitry Andric void DwarfExpression::maskSubRegister() {
4117a7e6055SDimitry Andric assert(SubRegisterSizeInBits && "no subregister was registered");
4127a7e6055SDimitry Andric if (SubRegisterOffsetInBits > 0)
4137a7e6055SDimitry Andric addShr(SubRegisterOffsetInBits);
4147a7e6055SDimitry Andric uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
4157a7e6055SDimitry Andric addAnd(Mask);
4167a7e6055SDimitry Andric }
4177a7e6055SDimitry Andric
finalize()418d88c1a5aSDimitry Andric void DwarfExpression::finalize() {
4197a7e6055SDimitry Andric assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
4207a7e6055SDimitry Andric // Emit any outstanding DW_OP_piece operations to mask out subregisters.
4217a7e6055SDimitry Andric if (SubRegisterSizeInBits == 0)
4227a7e6055SDimitry Andric return;
4237a7e6055SDimitry Andric // Don't emit a DW_OP_piece for a subregister at offset 0.
4247a7e6055SDimitry Andric if (SubRegisterOffsetInBits == 0)
4257a7e6055SDimitry Andric return;
4267a7e6055SDimitry Andric addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
427d88c1a5aSDimitry Andric }
428d88c1a5aSDimitry Andric
addFragmentOffset(const DIExpression * Expr)429d88c1a5aSDimitry Andric void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
430d88c1a5aSDimitry Andric if (!Expr || !Expr->isFragment())
431d88c1a5aSDimitry Andric return;
432d88c1a5aSDimitry Andric
433d88c1a5aSDimitry Andric uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
434d88c1a5aSDimitry Andric assert(FragmentOffset >= OffsetInBits &&
435d88c1a5aSDimitry Andric "overlapping or duplicate fragments");
436d88c1a5aSDimitry Andric if (FragmentOffset > OffsetInBits)
4377a7e6055SDimitry Andric addOpPiece(FragmentOffset - OffsetInBits);
438d88c1a5aSDimitry Andric OffsetInBits = FragmentOffset;
439d88c1a5aSDimitry Andric }
440