-/// EmitDwarfRegOp - Emit dwarf register operation.
-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);
- if (Reg >= 0)
- Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
- }
-
- // FIXME: Handle cases like a super register being encoded as
- // DW_OP_reg 32 DW_OP_piece 4 DW_OP_reg 33
-
- // FIXME: We have no reasonable way of handling errors in here. The
- // caller might be in the middle of an dwarf expression. We should
- // probably assert that Reg >= 0 once debug info generation is more mature.
- if (Reg < 0) {
- OutStreamer.AddComment("nop (invalid dwarf register number)");
- EmitInt8(dwarf::DW_OP_nop);
- return;
- }
-
- if (MLoc.isIndirect() || Indirect) {
- if (Reg < 32) {
- OutStreamer.AddComment(
- dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
- EmitInt8(dwarf::DW_OP_breg0 + Reg);
- } else {
- OutStreamer.AddComment("DW_OP_bregx");
- EmitInt8(dwarf::DW_OP_bregx);
- OutStreamer.AddComment(Twine(Reg));
- EmitULEB128(Reg);
- }
- EmitSLEB128(!MLoc.isIndirect() ? 0 : MLoc.getOffset());
- if (MLoc.isIndirect() && Indirect)
- EmitInt8(dwarf::DW_OP_deref);
- } else {
- if (Reg < 32) {
- OutStreamer.AddComment(
- dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));
- EmitInt8(dwarf::DW_OP_reg0 + Reg);
- } else {
- OutStreamer.AddComment("DW_OP_regx");
- EmitInt8(dwarf::DW_OP_regx);
- OutStreamer.AddComment(Twine(Reg));
- EmitULEB128(Reg);
- }
- }
-
- // 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);
- unsigned ByteSize = Size / 8; // Assuming 8 bits per byte.
- OutStreamer.AddComment(Twine(ByteSize));
- EmitULEB128(ByteSize);
- }
- }
-}
-