mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
Make provision to have floating point constants in .debug_loc expressions.
llvm-svn: 134702
This commit is contained in:
parent
560b1d3295
commit
756482ca98
@ -1449,11 +1449,20 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
DotDebugLocEntries.
|
||||
push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var));
|
||||
}
|
||||
// FIXME: Handle isFPImm also.
|
||||
else if (Begin->getOperand(0).isImm()) {
|
||||
DotDebugLocEntries.
|
||||
push_back(DotDebugLocEntry(FLabel, SLabel,
|
||||
Begin->getOperand(0).getImm()));
|
||||
} else if (Begin->getOperand(0).isFPImm()) {
|
||||
DotDebugLocEntries.
|
||||
push_back(DotDebugLocEntry(FLabel, SLabel,
|
||||
Begin->getOperand(0).getFPImm()));
|
||||
} else if (Begin->getOperand(0).isCImm()) {
|
||||
DotDebugLocEntries.
|
||||
push_back(DotDebugLocEntry(FLabel, SLabel,
|
||||
Begin->getOperand(0).getCImm()));
|
||||
} else {
|
||||
assert (0 && "Unexpected 3 operand DBG_VALUE instruction!");
|
||||
}
|
||||
} else {
|
||||
MLoc = Asm->getDebugValueLocation(Begin);
|
||||
@ -2608,56 +2617,61 @@ void DwarfDebug::emitDebugLoc() {
|
||||
MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
|
||||
Asm->EmitLabelDifference(end, begin, 2);
|
||||
Asm->OutStreamer.EmitLabel(begin);
|
||||
if (Entry.isConstant()) {
|
||||
if (Entry.isInt()) {
|
||||
DIBasicType BTy(DV.getType());
|
||||
if (BTy.Verify() &&
|
||||
(BTy.getEncoding() == dwarf::DW_ATE_signed
|
||||
|| BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
|
||||
Asm->OutStreamer.AddComment("DW_OP_consts");
|
||||
Asm->EmitInt8(dwarf::DW_OP_consts);
|
||||
Asm->EmitSLEB128(Entry.getConstant());
|
||||
Asm->EmitSLEB128(Entry.getInt());
|
||||
} else {
|
||||
Asm->OutStreamer.AddComment("DW_OP_constu");
|
||||
Asm->EmitInt8(dwarf::DW_OP_constu);
|
||||
Asm->EmitULEB128(Entry.getConstant());
|
||||
Asm->EmitULEB128(Entry.getInt());
|
||||
}
|
||||
} else if (DV.hasComplexAddress()) {
|
||||
unsigned N = DV.getNumAddrElements();
|
||||
unsigned i = 0;
|
||||
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
|
||||
if (Entry.Loc.getOffset()) {
|
||||
i = 2;
|
||||
Asm->EmitDwarfRegOp(Entry.Loc);
|
||||
Asm->OutStreamer.AddComment("DW_OP_deref");
|
||||
Asm->EmitInt8(dwarf::DW_OP_deref);
|
||||
Asm->OutStreamer.AddComment("DW_OP_plus_uconst");
|
||||
Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
|
||||
Asm->EmitSLEB128(DV.getAddrElement(1));
|
||||
} else {
|
||||
// If first address element is OpPlus then emit
|
||||
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
|
||||
MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1));
|
||||
Asm->EmitDwarfRegOp(Loc);
|
||||
i = 2;
|
||||
}
|
||||
} else {
|
||||
} else if (Entry.isLocation()) {
|
||||
if (!DV.hasComplexAddress())
|
||||
// Regular entry.
|
||||
Asm->EmitDwarfRegOp(Entry.Loc);
|
||||
else {
|
||||
// Complex address entry.
|
||||
unsigned N = DV.getNumAddrElements();
|
||||
unsigned i = 0;
|
||||
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
|
||||
if (Entry.Loc.getOffset()) {
|
||||
i = 2;
|
||||
Asm->EmitDwarfRegOp(Entry.Loc);
|
||||
Asm->OutStreamer.AddComment("DW_OP_deref");
|
||||
Asm->EmitInt8(dwarf::DW_OP_deref);
|
||||
Asm->OutStreamer.AddComment("DW_OP_plus_uconst");
|
||||
Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
|
||||
Asm->EmitSLEB128(DV.getAddrElement(1));
|
||||
} else {
|
||||
// If first address element is OpPlus then emit
|
||||
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
|
||||
MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1));
|
||||
Asm->EmitDwarfRegOp(Loc);
|
||||
i = 2;
|
||||
}
|
||||
} else {
|
||||
Asm->EmitDwarfRegOp(Entry.Loc);
|
||||
}
|
||||
|
||||
// Emit remaining complex address elements.
|
||||
for (; i < N; ++i) {
|
||||
uint64_t Element = DV.getAddrElement(i);
|
||||
if (Element == DIBuilder::OpPlus) {
|
||||
Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
|
||||
Asm->EmitULEB128(DV.getAddrElement(++i));
|
||||
} else if (Element == DIBuilder::OpDeref)
|
||||
Asm->EmitInt8(dwarf::DW_OP_deref);
|
||||
else llvm_unreachable("unknown Opcode found in complex address");
|
||||
}
|
||||
}
|
||||
|
||||
// Emit remaining complex address elements.
|
||||
for (; i < N; ++i) {
|
||||
uint64_t Element = DV.getAddrElement(i);
|
||||
if (Element == DIBuilder::OpPlus) {
|
||||
Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
|
||||
Asm->EmitULEB128(DV.getAddrElement(++i));
|
||||
} else if (Element == DIBuilder::OpDeref)
|
||||
Asm->EmitInt8(dwarf::DW_OP_deref);
|
||||
else llvm_unreachable("unknown Opcode found in complex address");
|
||||
}
|
||||
} else {
|
||||
// Regular entry.
|
||||
Asm->EmitDwarfRegOp(Entry.Loc);
|
||||
}
|
||||
// else ... ignore constant fp. There is not any good way to
|
||||
// to represent them here in dwarf.
|
||||
Asm->OutStreamer.EmitLabel(end);
|
||||
}
|
||||
}
|
||||
|
@ -69,17 +69,35 @@ typedef struct DotDebugLocEntry {
|
||||
const MDNode *Variable;
|
||||
bool Merged;
|
||||
bool Constant;
|
||||
int64_t iConstant;
|
||||
enum EntryType {
|
||||
E_Location,
|
||||
E_Integer,
|
||||
E_ConstantFP,
|
||||
E_ConstantInt
|
||||
};
|
||||
enum EntryType EntryKind;
|
||||
|
||||
union {
|
||||
int64_t Int;
|
||||
const ConstantFP *CFP;
|
||||
const ConstantInt *CIP;
|
||||
} Constants;
|
||||
DotDebugLocEntry()
|
||||
: Begin(0), End(0), Variable(0), Merged(false),
|
||||
Constant(false), iConstant(0) {}
|
||||
Constant(false) { Constants.Int = 0;}
|
||||
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, MachineLocation &L,
|
||||
const MDNode *V)
|
||||
: Begin(B), End(E), Loc(L), Variable(V), Merged(false),
|
||||
Constant(false), iConstant(0) {}
|
||||
Constant(false) { Constants.Int = 0; EntryKind = E_Location; }
|
||||
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, int64_t i)
|
||||
: Begin(B), End(E), Variable(0), Merged(false),
|
||||
Constant(true), iConstant(i) {}
|
||||
Constant(true) { Constants.Int = i; EntryKind = E_Integer; }
|
||||
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantFP *FPtr)
|
||||
: Begin(B), End(E), Variable(0), Merged(false),
|
||||
Constant(true) { Constants.CFP = FPtr; EntryKind = E_ConstantFP; }
|
||||
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantInt *IPtr)
|
||||
: Begin(B), End(E), Variable(0), Merged(false),
|
||||
Constant(true) { Constants.CIP = IPtr; EntryKind = E_ConstantInt; }
|
||||
|
||||
/// Empty entries are also used as a trigger to emit temp label. Such
|
||||
/// labels are referenced is used to find debug_loc offset for a given DIE.
|
||||
@ -91,8 +109,13 @@ typedef struct DotDebugLocEntry {
|
||||
Next->Begin = Begin;
|
||||
Merged = true;
|
||||
}
|
||||
bool isConstant() { return Constant; }
|
||||
int64_t getConstant() { return iConstant; }
|
||||
bool isLocation() const { return EntryKind == E_Location; }
|
||||
bool isInt() const { return EntryKind == E_Integer; }
|
||||
bool isConstantFP() const { return EntryKind == E_ConstantFP; }
|
||||
bool isConstantInt() const { return EntryKind == E_ConstantInt; }
|
||||
int64_t getInt() { return Constants.Int; }
|
||||
const ConstantFP *getConstantFP() { return Constants.CFP; }
|
||||
const ConstantInt *getConstantInt() { return Constants.CIP; }
|
||||
} DotDebugLocEntry;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user