//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "asm-printer"
+#include "ByteStreamer.h"
+#include "DwarfExpression.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
+#define DEBUG_TYPE "asm-printer"
+
+/// DwarfExpression implementation for .debug_loc entries.
+class DebugLocDwarfExpression : public DwarfExpression {
+ ByteStreamer &BS;
+public:
+ DebugLocDwarfExpression(TargetMachine &TM, ByteStreamer &BS)
+ : DwarfExpression(TM), BS(BS) {}
+
+ void EmitOp(uint8_t Op, const char* Comment) override;
+ void EmitSigned(int Value) override;
+ void EmitUnsigned(unsigned Value) override;
+ unsigned getFrameRegister() override {
+ llvm_unreachable("not available");
+ };
+};
+
+void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char* Comment) {
+ BS.EmitInt8(Op, Comment
+ ? Twine(Comment)+" "+dwarf::OperationEncodingString(Op)
+ : dwarf::OperationEncodingString(Op));
+}
+void DebugLocDwarfExpression::EmitSigned(int Value) {
+ BS.EmitSLEB128(Value, Twine(Value));
+}
+void DebugLocDwarfExpression::EmitUnsigned(unsigned Value) {
+ BS.EmitULEB128(Value, Twine(Value));
+}
+
+
//===----------------------------------------------------------------------===//
// Dwarf Emission Helper Routines
//===----------------------------------------------------------------------===//
default:
llvm_unreachable("Invalid encoded value.");
case dwarf::DW_EH_PE_absptr:
- return TM.getDataLayout()->getPointerSize();
+ return TM.getSubtargetImpl()->getDataLayout()->getPointerSize();
case dwarf::DW_EH_PE_udata2:
return 2;
case dwarf::DW_EH_PE_udata4:
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
const MCExpr *Exp =
- TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, MMI, OutStreamer);
+ TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI, OutStreamer);
OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
} else
OutStreamer.EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
EmitLabelDifference(Label, SectionLabel, 4);
}
+// Some targets do not provide a DWARF register number for every
+// register. This function attempts to emit a DWARF register by
+// emitting a piece of a super-register or by piecing together
+// multiple subregisters that alias the register.
+void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer,
+ const MachineLocation &MLoc,
+ unsigned PieceSizeInBits,
+ unsigned PieceOffsetInBits) const {
+ assert(MLoc.isReg() && "MLoc must be a register");
+ DebugLocDwarfExpression Expr(TM, Streamer);
+ Expr.AddMachineRegPiece(MLoc.getReg(), PieceSizeInBits, PieceOffsetInBits);
+}
+
+void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer,
+ unsigned PieceSizeInBits,
+ unsigned PieceOffsetInBits) const {
+ DebugLocDwarfExpression Expr(TM, Streamer);
+ Expr.AddOpPiece(PieceSizeInBits, PieceOffsetInBits);
+}
+
+/// EmitDwarfRegOp - Emit dwarf register operation.
+void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
+ const MachineLocation &MLoc,
+ bool Indirect) const {
+ DebugLocDwarfExpression Expr(TM, Streamer);
+ const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
+ int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
+ if (Reg < 0) {
+ // We assume that pointers are always in an addressable register.
+ if (Indirect || MLoc.isIndirect())
+ // FIXME: We have no reasonable way of handling errors in here. The
+ // caller might be in the middle of a dwarf expression. We should
+ // probably assert that Reg >= 0 once debug info generation is more
+ // mature.
+ return Expr.EmitOp(dwarf::DW_OP_nop,
+ "nop (could not find a dwarf register number)");
+
+ // Attempt to find a valid super- or sub-register.
+ return Expr.AddMachineRegPiece(MLoc.getReg());
+ }
+
+ if (MLoc.isIndirect())
+ Expr.AddRegIndirect(Reg, MLoc.getOffset(), Indirect);
+ else if (Indirect)
+ Expr.AddRegIndirect(Reg, 0, false);
+ else
+ Expr.AddReg(Reg);
+}
+
//===----------------------------------------------------------------------===//
// Dwarf Lowering Routines
//===----------------------------------------------------------------------===//
case MCCFIInstruction::OpWindowSave:
OutStreamer.EmitCFIWindowSave();
break;
+ case MCCFIInstruction::OpSameValue:
+ OutStreamer.EmitCFISameValue(Inst.getRegister());
+ break;
}
}