- // Walk up the super-register chain until we find a valid number.
- // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
- for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
- Reg = TRI->getDwarfRegNum(*SR, false);
- if (Reg >= 0) {
- unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
- unsigned Size = TRI->getSubRegIdxSize(Idx);
- unsigned Offset = TRI->getSubRegIdxOffset(Idx);
- OutStreamer.AddComment("super-register");
- emitDwarfRegOp(Streamer, Reg);
- if (PieceOffsetInBits == Offset) {
- emitDwarfOpPiece(Streamer, Size, Offset);
- } else {
- // If this is part of a variable in a sub-register at a
- // non-zero offset, we need to manually shift the value into
- // place, since the DW_OP_piece describes the part of the
- // variable, not the position of the subregister.
- emitDwarfOpPiece(Streamer, Size, PieceOffsetInBits);
- if (Offset)
- emitDwarfOpShr(Streamer, Offset);
- }
- return;
- }
- }
-
- // Otherwise, attempt to find a covering set of sub-register numbers.
- // For example, Q0 on ARM is a composition of D0+D1.
- //
- // Keep track of the current position so we can emit the more
- // efficient DW_OP_piece.
- unsigned CurPos = PieceOffsetInBits;
- // The size of the register in bits, assuming 8 bits per byte.
- unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize() * 8;
- // Keep track of the bits in the register we already emitted, so we
- // can avoid emitting redundant aliasing subregs.
- SmallBitVector Coverage(RegSize, false);
- for (MCSubRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
- unsigned Idx = TRI->getSubRegIndex(MLoc.getReg(), *SR);
- unsigned Size = TRI->getSubRegIdxSize(Idx);
- unsigned Offset = TRI->getSubRegIdxOffset(Idx);
- Reg = TRI->getDwarfRegNum(*SR, false);
-
- // Intersection between the bits we already emitted and the bits
- // covered by this subregister.
- SmallBitVector Intersection(RegSize, false);
- Intersection.set(Offset, Offset + Size);
- Intersection ^= Coverage;
-
- // If this sub-register has a DWARF number and we haven't covered
- // its range, emit a DWARF piece for it.
- if (Reg >= 0 && Intersection.any()) {
- OutStreamer.AddComment("sub-register");
- emitDwarfRegOp(Streamer, Reg);
- emitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset);
- CurPos = Offset + Size;
-
- // Mark it as emitted.
- Coverage.set(Offset, Offset + Size);
- }
- }
-
- if (CurPos == PieceOffsetInBits) {
- // FIXME: We have no reasonable way of handling errors in here.
- Streamer.EmitInt8(dwarf::DW_OP_nop,
- "nop (could not find a dwarf register number)");
- }