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 @@ -375,6 +375,20 @@ S << MRI->getName(*LLVMRegNum); break; } + case dwarf::DW_OP_bregx: { + int DwarfRegNum = Op.getRawOperand(0); + int64_t Offset = Op.getRawOperand(1); + Optional LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, false); + if (!LLVMRegNum) { + OS << ""; + return false; + } + raw_svector_ostream S(Stack.emplace_back().String); + S << MRI->getName(*LLVMRegNum); + if (Offset) + S << format("%+" PRId64, Offset); + break; + } default: if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) { // DW_OP_reg: A register, with the register num implied by the @@ -387,6 +401,19 @@ } raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String); S << MRI->getName(*LLVMRegNum); + } else if (Opcode >= dwarf::DW_OP_breg0 && + Opcode <= dwarf::DW_OP_breg31) { + int DwarfRegNum = Opcode - dwarf::DW_OP_breg0; + int64_t Offset = Op.getRawOperand(0); + Optional LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, false); + if (!LLVMRegNum) { + OS << ""; + return false; + } + raw_svector_ostream S(Stack.emplace_back().String); + S << MRI->getName(*LLVMRegNum); + if (Offset) + S << format("%+" PRId64, Offset); } else { // If we hit an unknown operand, we don't know its effect on the stack, // so bail out on the whole expression. @@ -400,7 +427,11 @@ } assert(Stack.size() == 1 && "expected one value on stack"); - OS << Stack.front().String; + + if (Stack.front().Kind == PrintedExpr::Address) + OS << "[" << Stack.front().String << "]"; + else + OS << Stack.front().String; return true; } diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp @@ -71,3 +71,27 @@ TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_regx) { TestExprPrinter({DW_OP_regx, 0x80, 0x02}, "D0"); } + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0) { + TestExprPrinter({DW_OP_breg0, 0x04}, "[R0+4]"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0_large_offset) { + TestExprPrinter({DW_OP_breg0, 0x80, 0x02}, "[R0+256]"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg13) { + TestExprPrinter({DW_OP_breg13, 0x10}, "[SP+16]"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg13_zero_offset) { + TestExprPrinter({DW_OP_breg13, 0x00}, "[SP]"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0_negative) { + TestExprPrinter({DW_OP_breg0, 0x70}, "[R0-16]"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_bregx) { + TestExprPrinter({DW_OP_bregx, 0x0d, 0x28}, "[SP+40]"); +}