EmitOp(dwarf::DW_OP_shr);
}
+bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
+ const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
+ int DwarfReg = TRI->getDwarfRegNum(MachineReg, false);
+ if (DwarfReg < 0)
+ return false;
+
+ if (MachineReg == getFrameRegister()) {
+ // If variable offset is based in frame register then use fbreg.
+ EmitOp(dwarf::DW_OP_fbreg);
+ EmitSigned(Offset);
+ } else {
+ AddRegIndirect(DwarfReg, Offset);
+ }
+ return true;
+}
+
void DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
unsigned PieceSizeInBits,
unsigned PieceOffsetInBits) {
/// independently of whether they are emitted into a DIE or into a .debug_loc
/// entry.
class DwarfExpression {
+protected:
TargetMachine &TM;
public:
DwarfExpression(TargetMachine &TM) : TM(TM) {}
virtual void EmitOp(uint8_t Op, const char* Comment = nullptr) = 0;
virtual void EmitSigned(int Value) = 0;
virtual void EmitUnsigned(unsigned Value) = 0;
+
+ virtual unsigned getFrameRegister() = 0;
+
/// Emit a dwarf register operation.
void AddReg(int DwarfReg, const char* Comment = nullptr);
/// Emit an (double-)indirect dwarf register operation.
/// Emit a shift-right dwarf expression.
void AddShr(unsigned ShiftBy);
+ /// Emit an indirect dwarf register operation for the given machine register.
+ /// Returns false if no DWARF register exists for MachineReg.
+ bool AddMachineRegIndirect(unsigned MachineReg, int Offset);
+
/// \brief Emit a partial DWARF register operation.
/// \param MLoc the register
/// \param PieceSize size and
#include "DwarfAccelTable.h"
#include "DwarfCompileUnit.h"
#include "DwarfDebug.h"
+#include "DwarfExpression.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
cl::desc("Generate DWARF4 type units."),
cl::init(false));
+/// DwarfExpression implementation for DwarfUnit.
+class DIEDwarfExpression : public DwarfExpression {
+ DwarfUnit &DU;
+ DIELoc &DIE;
+public:
+ DIEDwarfExpression(TargetMachine &TM, DwarfUnit &DU, DIELoc &DIE)
+ : DwarfExpression(TM), DU(DU), DIE(DIE) {}
+
+ void EmitOp(uint8_t Op, const char* Comment = nullptr) override;
+ void EmitSigned(int Value) override;
+ void EmitUnsigned(unsigned Value) override;
+ unsigned getFrameRegister() override;
+};
+
+void DIEDwarfExpression::EmitOp(uint8_t Op, const char* Comment) {
+ DU.addUInt(DIE, dwarf::DW_FORM_data1, Op);
+}
+void DIEDwarfExpression::EmitSigned(int Value) {
+ DU.addSInt(DIE, dwarf::DW_FORM_sdata, Value);
+}
+void DIEDwarfExpression::EmitUnsigned(unsigned Value) {
+ DU.addUInt(DIE, dwarf::DW_FORM_udata, Value);
+}
+unsigned DIEDwarfExpression::getFrameRegister() {
+ const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
+ return TRI->getFrameRegister(*DU.getAsmPrinter()->MF);
+}
+
+
/// Unit - Unit constructor.
DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag, DICompileUnit Node,
AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
/// addRegisterOffset - Add register offset.
bool DwarfUnit::addRegisterOffset(DIELoc &TheDie, unsigned Reg,
int64_t Offset) {
- const TargetRegisterInfo *TRI = Asm->TM.getSubtargetImpl()->getRegisterInfo();
- int DWReg = TRI->getDwarfRegNum(Reg, false);
- if (DWReg < 0)
- return false;
-
- if (Reg == TRI->getFrameRegister(*Asm->MF))
- // If variable offset is based in frame register then use fbreg.
- addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
- else if (DWReg < 32)
- addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
- else {
- addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
- addUInt(TheDie, dwarf::DW_FORM_udata, DWReg);
- }
- addSInt(TheDie, dwarf::DW_FORM_sdata, Offset);
- return true;
+ DIEDwarfExpression Expr(Asm->TM, *this, TheDie);
+ return Expr.AddMachineRegIndirect(Reg, Offset);
}
/* Byref variables, in Blocks, are declared by the programmer as "SomeType