Dwarf info for byref register variables

Two functions in DwarfDebug, addBlockByrefAddress() and
addComplexAddress(), contain this snippet of code:

  // Decode the original location, and use that as the start of the byref
  // variable's location.
  const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
  unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
  DIEBlock *Block = new (DIEValueAllocator) DIEBlock();

  if (Location.isReg()) {
    if (Reg < 32)
      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
    else {
      Reg = Reg - dwarf::DW_OP_reg0;
      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
    }
  } else {
    if (Reg < 32)
      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
    else {
      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
    }

    addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
  }

What's going on in the 'else' block of the first nested 'if' (where
Location.isReg() && Reg >=32)? It looks wrong to me.

If you expand out the opcode parameter, you get:

  Opcode = DW_OP_breg0 + Reg
         = DW_OP_breg0 + (RegOriginal - DW_OP_reg0)
         = RegOriginal + (DW_OP_breg0 - DW_OP_reg0)
         = RegOriginal + (0x70 - 0x50)
         = RegOriginal + 0x20
         = RegOriginal + DW_OP_not

Since we know that RegOriginal >= 32, the opcode that gets generated
is one that has a value >= 0x40, which is DW_OP_lit16.

There is a very similar snippet in the addAddress() function. It uses
the DW_OP_regx opcode to encode the register number:

  // ...
  if (Location.isReg()) {
    if (Reg < 32) {
      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
    } else {
      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
    }
  } else {
  // ...

Should addBlockByrefAddress() and addComplexAddress() be doing the same?

-Ken

Yes. Can you prepare a patch ?
Thanks,

Sure. Attached.

-Ken

DwarfDebug-byref.register.vars.diff (984 Bytes)