aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfExpression.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfExpression.cpp33
1 files changed, 20 insertions, 13 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index d96479f43433..fe38ee805682 100644
--- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -248,15 +248,25 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
assert(Reg.Size == 0 && "subregister has same size as superregister");
// Pattern-match combinations for which more efficient representations exist.
- // [Reg, Offset, DW_OP_plus] --> [DW_OP_breg, Offset].
- // [Reg, Offset, DW_OP_minus] --> [DW_OP_breg, -Offset].
- // If Reg is a subregister we need to mask it out before subtracting.
- if (Op && ((Op->getOp() == dwarf::DW_OP_plus) ||
- (Op->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
- int Offset = Op->getArg(0);
- SignedOffset = (Op->getOp() == dwarf::DW_OP_plus) ? Offset : -Offset;
+ // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
+ if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
+ SignedOffset = Op->getArg(0);
ExprCursor.take();
}
+
+ // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
+ // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
+ // If Reg is a subregister we need to mask it out before subtracting.
+ if (Op && Op->getOp() == dwarf::DW_OP_constu) {
+ auto N = ExprCursor.peekNext();
+ if (N && (N->getOp() == dwarf::DW_OP_plus ||
+ (N->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
+ int Offset = Op->getArg(0);
+ SignedOffset = (N->getOp() == dwarf::DW_OP_minus) ? -Offset : Offset;
+ ExprCursor.consume(2);
+ }
+ }
+
if (FBReg)
addFBReg(SignedOffset);
else
@@ -320,17 +330,14 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
LocationKind = Unknown;
return;
}
- case dwarf::DW_OP_plus:
+ case dwarf::DW_OP_plus_uconst:
assert(LocationKind != Register);
emitOp(dwarf::DW_OP_plus_uconst);
emitUnsigned(Op->getArg(0));
break;
+ case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
- assert(LocationKind != Register);
- // There is no DW_OP_minus_uconst.
- emitOp(dwarf::DW_OP_constu);
- emitUnsigned(Op->getArg(0));
- emitOp(dwarf::DW_OP_minus);
+ emitOp(Op->getOp());
break;
case dwarf::DW_OP_deref: {
assert(LocationKind != Register);