diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 25 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 35 |
2 files changed, 56 insertions, 4 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index bab8aad497..09aedc4cc9 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -868,12 +868,14 @@ void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc, bool Indirect) const { const TargetRegisterInfo *TRI = TM.getRegisterInfo(); int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false); + bool isSubRegister = Reg < 0; + unsigned Idx = 0; for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid() && Reg < 0; ++SR) { Reg = TRI->getDwarfRegNum(*SR, false); - // FIXME: Get the bit range this register uses of the superregister - // so that we can produce a DW_OP_bit_piece + if (Reg >= 0) + Idx = TRI->getSubRegIndex(*SR, MLoc.getReg()); } // FIXME: Handle cases like a super register being encoded as @@ -910,7 +912,24 @@ void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc, } } - // FIXME: Produce a DW_OP_bit_piece if we used a superregister + // Emit Mask + if (isSubRegister) { + unsigned Size = TRI->getSubRegIdxSize(Idx); + unsigned Offset = TRI->getSubRegIdxOffset(Idx); + if (Offset > 0) { + OutStreamer.AddComment("DW_OP_bit_piece"); + EmitInt8(dwarf::DW_OP_bit_piece); + OutStreamer.AddComment(Twine(Size)); + EmitULEB128(Size); + OutStreamer.AddComment(Twine(Offset)); + EmitULEB128(Offset); + } else { + OutStreamer.AddComment("DW_OP_piece"); + EmitInt8(dwarf::DW_OP_piece); + OutStreamer.AddComment(Twine(Size)); + EmitULEB128(Size); + } + } } bool AsmPrinter::doFinalization(Module &M) { diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index a1db1e0a2e..6c9e40b066 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Mangler.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/CommandLine.h" @@ -476,13 +477,45 @@ void DwarfUnit::addVariableAddress(const DbgVariable &DV, DIE *Die, /// addRegisterOp - Add register operand. void DwarfUnit::addRegisterOp(DIEBlock *TheDie, unsigned Reg) { const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); - unsigned DWReg = RI->getDwarfRegNum(Reg, false); + int DWReg = RI->getDwarfRegNum(Reg, false); + bool isSubRegister = DWReg < 0; + + unsigned Idx = 0; + + // Go up the super-register chain until we hit a valid dwarf register number. + for (MCSuperRegIterator SR(Reg, RI); SR.isValid() && DWReg < 0; ++SR) { + DWReg = RI->getDwarfRegNum(*SR, false); + if (DWReg >= 0) + Idx = RI->getSubRegIndex(*SR, Reg); + } + + if (DWReg < 0) { + DEBUG(llvm::dbgs() << "Invalid Dwarf register number.\n"); + addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_nop); + return; + } + + // Emit register if (DWReg < 32) addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg); else { addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); addUInt(TheDie, dwarf::DW_FORM_udata, DWReg); } + + // Emit Mask + if (isSubRegister) { + unsigned Size = RI->getSubRegIdxSize(Idx); + unsigned Offset = RI->getSubRegIdxOffset(Idx); + if (Offset > 0) { + addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_bit_piece); + addUInt(TheDie, dwarf::DW_FORM_data1, Size); + addUInt(TheDie, dwarf::DW_FORM_data1, Offset); + } else { + addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_piece); + addUInt(TheDie, dwarf::DW_FORM_data1, Size); + } + } } /// addRegisterOffset - Add register offset. |