diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -2794,21 +2794,21 @@ of Operands ================================== ===== ======== =============================== - DW_OP_LLVM_form_aspace_address 0xe7 0 - DW_OP_LLVM_push_lane 0xea 0 - DW_OP_LLVM_offset 0xe9 0 - DW_OP_LLVM_offset_uconst *TBD* 1 ULEB128 byte displacement - DW_OP_LLVM_bit_offset *TBD* 0 - DW_OP_LLVM_call_frame_entry_reg *TBD* 1 ULEB128 register number - DW_OP_LLVM_undefined *TBD* 0 - DW_OP_LLVM_aspace_bregx *TBD* 2 ULEB128 register number, + DW_OP_LLVM_form_aspace_address 0xe1 0 + DW_OP_LLVM_push_lane 0xe2 0 + DW_OP_LLVM_offset 0xe3 0 + DW_OP_LLVM_offset_uconst 0xe4 1 ULEB128 byte displacement + DW_OP_LLVM_bit_offset 0xe5 0 + DW_OP_LLVM_call_frame_entry_reg 0xe6 1 ULEB128 register number + DW_OP_LLVM_undefined 0xe7 0 + DW_OP_LLVM_aspace_bregx 0xe8 2 ULEB128 register number, ULEB128 byte displacement - DW_OP_LLVM_aspace_implicit_pointer *TBD* 2 4- or 8-byte offset of DIE, + DW_OP_LLVM_aspace_implicit_pointer 0xe9 2 4- or 8-byte offset of DIE, SLEB128 byte displacement - DW_OP_LLVM_piece_end *TBD* 0 - DW_OP_LLVM_extend *TBD* 2 ULEB128 bit size, + DW_OP_LLVM_piece_end 0xea 0 + DW_OP_LLVM_extend 0xeb 2 ULEB128 bit size, ULEB128 count - DW_OP_LLVM_select_bit_piece *TBD* 2 ULEB128 bit size, + DW_OP_LLVM_select_bit_piece 0xec 2 ULEB128 bit size, ULEB128 count ================================== ===== ======== =============================== diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -665,6 +665,20 @@ // Extensions for Fission proposal. HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU) HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU) +// Extensions for AMDGPU proposal. +// FIXME: These collide with some HP and PGI vendor extensions. +HANDLE_DW_OP(0xe1, LLVM_form_aspace_address, 4, LLVM) +HANDLE_DW_OP(0xe2, LLVM_push_lane, 4, LLVM) +HANDLE_DW_OP(0xe3, LLVM_offset, 4, LLVM) +HANDLE_DW_OP(0xe4, LLVM_offset_uconst, 4, LLVM) +HANDLE_DW_OP(0xe5, LLVM_bit_offset, 4, LLVM) +HANDLE_DW_OP(0xe6, LLVM_call_frame_entry_reg, 4, LLVM) +HANDLE_DW_OP(0xe7, LLVM_undefined, 4, LLVM) +HANDLE_DW_OP(0xe8, LLVM_aspace_bregx, 4, LLVM) +HANDLE_DW_OP(0xe9, LLVM_aspace_implicit_pointer, 4, LLVM) +HANDLE_DW_OP(0xea, LLVM_piece_end, 4, LLVM) +HANDLE_DW_OP(0xeb, LLVM_extend, 4, LLVM) +HANDLE_DW_OP(0xec, LLVM_select_bit_piece, 4, LLVM) // DWARF languages. HANDLE_DW_LANG(0x0001, C89, 0, 2, DWARF) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -100,6 +100,21 @@ Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB); Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_LLVM_form_aspace_address] = Desc(Op::Dwarf4); + Descriptions[DW_OP_LLVM_push_lane] = Desc(Op::Dwarf4); + Descriptions[DW_OP_LLVM_offset] = Desc(Op::Dwarf4); + Descriptions[DW_OP_LLVM_offset_uconst] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_LLVM_bit_offset] = Desc(Op::Dwarf4); + Descriptions[DW_OP_LLVM_call_frame_entry_reg] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_LLVM_undefined] = Desc(Op::Dwarf4); + Descriptions[DW_OP_LLVM_aspace_bregx] = + Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeLEB); + Descriptions[DW_OP_LLVM_aspace_implicit_pointer] = + Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB); + Descriptions[DW_OP_LLVM_piece_end] = Desc(Op::Dwarf4); + Descriptions[DW_OP_LLVM_extend] = Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeLEB); + Descriptions[DW_OP_LLVM_select_bit_piece] = + Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeLEB); Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef); Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB); @@ -213,8 +228,10 @@ unsigned OpNum = 0; if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx || - Opcode == DW_OP_regval_type) + Opcode == DW_OP_regval_type || Opcode == DW_OP_LLVM_aspace_bregx) DwarfRegNum = Operands[OpNum++]; + else if (Opcode == DW_OP_LLVM_call_frame_entry_reg) + DwarfRegNum = Operands[OpNum]; else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx) DwarfRegNum = Opcode - DW_OP_breg0; else @@ -223,7 +240,7 @@ if (Optional LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) { if (const char *RegName = MRI->getName(*LLVMRegNum)) { if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || - Opcode == DW_OP_bregx) + Opcode == DW_OP_bregx || Opcode == DW_OP_LLVM_aspace_bregx) OS << format(" %s%+" PRId64, RegName, Operands[OpNum]); else OS << ' ' << RegName; @@ -254,7 +271,9 @@ if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) || Opcode == DW_OP_bregx || Opcode == DW_OP_regx || - Opcode == DW_OP_regval_type) + Opcode == DW_OP_regval_type || + Opcode == DW_OP_LLVM_call_frame_entry_reg || + Opcode == DW_OP_LLVM_aspace_bregx) if (prettyPrintRegisterOp(U, OS, Opcode, Operands, RegInfo, isEH)) return true; diff --git a/llvm/test/tools/llvm-dwarfdump/X86/amdgpu_proposal.s b/llvm/test/tools/llvm-dwarfdump/X86/amdgpu_proposal.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/amdgpu_proposal.s @@ -0,0 +1,40 @@ +# RUN: llvm-mc %s -filetype=obj -triple=i686-pc-linux -o %t +# RUN: llvm-dwarfdump -v %t | FileCheck %s + +# Check that we can decode new ops described at +# llvm/docs/AMDGPUUsage.rst#expression-operation-encodings + +# FIXME: Is there a better approach than using `DW_CFA_expression reg0 `? + +# CHECK: .eh_frame contents: +# CHECK: FDE + +foo: + .cfi_startproc + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_form_aspace_address + .cfi_escape 0x10, 0x00, 0x01, 0xe1 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_push_lane + .cfi_escape 0x10, 0x00, 0x01, 0xe2 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_offset + .cfi_escape 0x10, 0x00, 0x01, 0xe3 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_offset_uconst 0x0 + .cfi_escape 0x10, 0x00, 0x02, 0xe4, 0x00 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_bit_offset + .cfi_escape 0x10, 0x00, 0x01, 0xe5 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_call_frame_entry_reg EAX + .cfi_escape 0x10, 0x00, 0x02, 0xe6, 0x00 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_undefined + .cfi_escape 0x10, 0x00, 0x01, 0xe7 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_aspace_bregx EAX+2 + .cfi_escape 0x10, 0x00, 0x03, 0xe8, 0x0, 0x2 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_aspace_implicit_pointer 0x1 +2 + .cfi_escape 0x10, 0x00, 0x06, 0xe9, 0x1, 0x0, 0x0, 0x0, 0x2 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_piece_end + .cfi_escape 0x10, 0x00, 0x01, 0xea + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_extend 0x0 0x0 + .cfi_escape 0x10, 0x00, 0x03, 0xeb, 0x0, 0x0 + # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_select_bit_piece 0x0 0x0 + .cfi_escape 0x10, 0x00, 0x03, 0xec, 0x0, 0x0 + .cfi_endproc + +# CHECK-NEXT: DW_CFA_nop: