Index: lib/CodeGen/AsmPrinter/DwarfExpression.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfExpression.h +++ lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -59,10 +59,6 @@ /// - a small value occupying only part of a register or /// - a register representing only part of a value. void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0); - /// Emit a shift-left dwarf expression. - void AddShl(unsigned ShiftBy); - /// Emit a shift-right dwarf expression. - void AddShr(unsigned ShiftBy); /// Emit an indirect dwarf register operation for the given machine register. /// \return false if no DWARF register exists for MachineReg. Index: lib/CodeGen/AsmPrinter/DwarfExpression.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -59,18 +59,6 @@ } } -void DwarfExpression::AddShl(unsigned ShiftBy) { - EmitOp(dwarf::DW_OP_constu); - EmitUnsigned(ShiftBy); - EmitOp(dwarf::DW_OP_shl); -} - -void DwarfExpression::AddShr(unsigned ShiftBy) { - EmitOp(dwarf::DW_OP_constu); - EmitUnsigned(ShiftBy); - EmitOp(dwarf::DW_OP_shr); -} - bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { if (isFrameRegister(MachineReg)) { // If variable offset is based in frame register then use fbreg. @@ -109,23 +97,32 @@ Reg = TRI.getDwarfRegNum(*SR, false); if (Reg >= 0) { unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); - unsigned Size = TRI.getSubRegIdxSize(Idx); - unsigned SubRegOffset = TRI.getSubRegIdxOffset(Idx); - unsigned SuperSize = TRI.getRegClass(*SR)->getSize() * 8; - assert(SuperSize >= (SubRegOffset + Size)); + uint64_t Size = TRI.getSubRegIdxSize(Idx); + uint64_t SubRegOffset = TRI.getSubRegIdxOffset(Idx); + // +--------------+------+-----------+ + // | SubRegOffset | Size | UpperBits | + // +--------------+------+-----------+ AddReg(Reg, "super-register"); - // Mask out the uninteresting higher bits by shifting left first. - unsigned UpperBits = SuperSize - (SubRegOffset+Size); - if (UpperBits) - AddShl(UpperBits); - // 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. - if (SubRegOffset+UpperBits) - AddShr(SubRegOffset+UpperBits); + // If this is 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. + if (SubRegOffset > 0) { + EmitOp(dwarf::DW_OP_constu); + EmitUnsigned(SubRegOffset); + EmitOp(dwarf::DW_OP_shr); + } + if (Size > PieceSizeInBits) { + // Mask out the uninteresting higher bits. + // Use a DW_OP_and with a constant for this, because the size of DWARF + // stack elements is not well defined. + assert(Size <= 64 && "cannot create a mask larger than 64 bits"); + uint64_t Mask = ~uint64_t(0ULL) >> (64 - Size); + EmitOp(dwarf::DW_OP_constu); + EmitUnsigned(Mask); + EmitOp(dwarf::DW_OP_and); + } if (PieceSizeInBits) - AddOpPiece(Size, PieceOffsetInBits); + AddOpPiece(PieceSizeInBits, PieceOffsetInBits); return true; } } Index: test/CodeGen/ARM/debug-info-s16-reg.ll =================================================================== --- test/CodeGen/ARM/debug-info-s16-reg.ll +++ test/CodeGen/ARM/debug-info-s16-reg.ll @@ -3,8 +3,9 @@ ; Test dwarf reg no for s16 ;CHECK: super-register DW_OP_regx ;CHECK-NEXT: 264 -;CHECK-NEXT: DW_OP_piece -;CHECK-NEXT: 4 +;CHECK-NEXT: DW_OP_constu +;CHECK-NEXT: 4294967295 +;CHECK-NEXT: DW_OP_and target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" target triple = "thumbv7-apple-macosx10.6.7" Index: test/CodeGen/ARM/debug-info-sreg2.ll =================================================================== --- test/CodeGen/ARM/debug-info-sreg2.ll +++ test/CodeGen/ARM/debug-info-sreg2.ll @@ -7,10 +7,10 @@ ; of the size of the location description. ; ; 0x90 DW_OP_regx of super-register - ; CHECK: 0x00000000: Beginning address offset: ; CHECK-NEXT: Ending address offset: -; CHECK-NEXT: Location description: 90 {{.. .. .. .. $}} +; d8, constu 0xffffffff, and +; CHECK-NEXT: Location description: 90 88 02 10 ff ff ff ff 0f 1a define void @_Z3foov() optsize ssp { entry: Index: test/DebugInfo/ARM/s-super-register.ll =================================================================== --- test/DebugInfo/ARM/s-super-register.ll +++ test/DebugInfo/ARM/s-super-register.ll @@ -5,9 +5,8 @@ ; The S registers on ARM are expressed as pieces of their super-registers in DWARF. ; ; 0x90 DW_OP_regx of super-register -; 0x93 DW_OP_piece -; 0x9d DW_OP_bit_piece -; CHECK: Location description: 90 {{.. .. ((93 ..)|(9d .. ..)) $}} +; d8, constu 0xffffffff, and +; CHECK: Location description: 90 88 02 10 ff ff ff ff 0f 1a define void @_Z3foov() optsize ssp { entry: Index: test/DebugInfo/X86/dbg-value-const-byref.ll =================================================================== --- test/DebugInfo/X86/dbg-value-const-byref.ll +++ test/DebugInfo/X86/dbg-value-const-byref.ll @@ -34,10 +34,10 @@ ; CHECK: Beginning address offset: [[C1]] ; CHECK: Ending address offset: [[C2:.*]] ; CHECK: Location description: 11 07 -; rax, piece 0x00000004 +; rax & 0xffffffff ; CHECK: Beginning address offset: [[C2]] ; CHECK: Ending address offset: [[R1:.*]] -; CHECK: Location description: 50 93 04 +; CHECK: Location description: 50 10 ff ff ff ff 0f 1a ; rdi+0 ; CHECK: Beginning address offset: [[R1]] ; CHECK: Ending address offset: [[R2:.*]] Index: test/DebugInfo/X86/fission-ranges.ll =================================================================== --- test/DebugInfo/X86/fission-ranges.ll +++ test/DebugInfo/X86/fission-ranges.ll @@ -30,16 +30,16 @@ ; CHECK-NEXT: {{^$}} ; CHECK-NEXT: Beginning address index: 3 ; CHECK-NEXT: Length: 23 -; CHECK-NEXT: Location description: 50 93 04 +; CHECK-NEXT: Location description: 50 10 ff ff ff ff 0f 1a ; CHECK: [[E]]: Beginning address index: 4 ; CHECK-NEXT: Length: 21 -; CHECK-NEXT: Location description: 50 93 04 +; CHECK-NEXT: Location description: 50 10 ff ff ff ff 0f 1a ; CHECK: [[B]]: Beginning address index: 5 ; CHECK-NEXT: Length: 19 -; CHECK-NEXT: Location description: 50 93 04 +; CHECK-NEXT: Location description: 50 10 ff ff ff ff 0f 1a ; CHECK: [[D]]: Beginning address index: 6 ; CHECK-NEXT: Length: 23 -; CHECK-NEXT: Location description: 50 93 04 +; CHECK-NEXT: Location description: 50 10 ff ff ff ff 0f 1a ; Make sure we don't produce any relocations in any .dwo section (though in particular, debug_info.dwo) ; HDR-NOT: .rela.{{.*}}.dwo Index: test/DebugInfo/X86/subreg.ll =================================================================== --- test/DebugInfo/X86/subreg.ll +++ test/DebugInfo/X86/subreg.ll @@ -5,7 +5,9 @@ ; CHECK: .byte 80 # super-register DW_OP_reg0 ; CHECK-NEXT: .byte 147 # DW_OP_piece -; CHECK-NEXT: .byte 2 # 2 +; CHECK-NEXT: DW_OP_constu +; CHECK-NEXT: 4294967295 +; CHECK-NEXT: DW_OP_and define i16 @f(i16 signext %zzz) nounwind { entry: