diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2024-11-11 11:38:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-11 11:38:36 -0800 |
commit | 74003f11b3e4dd90665f8f8d911f40a22dd940d4 (patch) | |
tree | 8ce8a326f4b2cd49e3eec4bd0f8c0d12644ca8b1 /llvm/lib/MC/MCDwarf.cpp | |
parent | b242ae32f56372d7858945df72ce2f00f7e97bc3 (diff) | |
download | llvm-74003f11b3e4dd90665f8f8d911f40a22dd940d4.zip llvm-74003f11b3e4dd90665f8f8d911f40a22dd940d4.tar.gz llvm-74003f11b3e4dd90665f8f8d911f40a22dd940d4.tar.bz2 |
[mc] Add CFI directive to emit val_offset() rules (#113971)
These specify that the value of the given register in the previous frame
is the CFA plus some offset. This isn't very common but can be necessary
if the original value is normally reconstructed from the stack/frame
pointer instead of being saved on the stack and reloaded from there.
Diffstat (limited to 'llvm/lib/MC/MCDwarf.cpp')
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index e058358..552822e 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1503,6 +1503,25 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) { case MCCFIInstruction::OpLabel: Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc()); return; + case MCCFIInstruction::OpValOffset: { + unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg); + + int Offset = Instr.getOffset(); + Offset = Offset / dataAlignmentFactor; + + if (Offset < 0) { + Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf); + Streamer.emitULEB128IntValue(Reg); + Streamer.emitSLEB128IntValue(Offset); + } else { + Streamer.emitInt8(dwarf::DW_CFA_val_offset); + Streamer.emitULEB128IntValue(Reg); + Streamer.emitULEB128IntValue(Offset); + } + return; + } } llvm_unreachable("Unhandled case in switch"); } |