llvm-project/llvm/lib/Support/ARMWinEH.cpp
Martin Storsjö d4257fbbba [llvm-readobj] Improve printing of Windows ARM packed unwind info
Fix a couple minor details in the existing logic for calculating
saved registers and stack adjustment.

Synthesize the corresponding prologues and epilogues and print them.
(This supersedes the previous printout of one single list of stored
registers; as there's lots of minor nuance differences in how
registers are pushed/popped in various corner cases, it's better to
print the full prologue/epilogue instead of trying to condense it
into one single list.)

Print the raw values of the fields Reg, R, L (LinkRegister) and C
(Chaining) instead of only printing the derived values.

Differential Revision: https://reviews.llvm.org/D125644
2022-05-18 21:33:08 +03:00

50 lines
1.6 KiB
C++

//===-- ARMWinEH.cpp - Windows on ARM EH Support Functions ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/ARMWinEH.h"
namespace llvm {
namespace ARM {
namespace WinEH {
std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF,
bool Prologue) {
uint8_t NumRegisters = RF.Reg();
uint8_t RegistersVFP = RF.R();
uint8_t LinkRegister = RF.L();
uint8_t ChainedFrame = RF.C();
uint16_t GPRMask = (ChainedFrame << 11);
uint32_t VFPMask = 0;
if (Prologue) {
GPRMask |= (LinkRegister << 14);
} else {
// If Ret != 0, we pop into Lr and return later
if (RF.Ret() != ReturnType::RT_POP)
GPRMask |= (LinkRegister << 14);
else if (!RF.H()) // If H == 0, we pop directly into Pc
GPRMask |= (LinkRegister << 15);
// else, Ret == 0 && H == 1, we pop into Pc separately afterwards
}
if (RegistersVFP)
VFPMask |= (((1 << ((NumRegisters + 1) % 8)) - 1) << 8);
else
GPRMask |= (((1 << (NumRegisters + 1)) - 1) << 4);
if ((PrologueFolding(RF) && Prologue) || (EpilogueFolding(RF) && !Prologue))
GPRMask |= (((1 << ((RF.StackAdjust() & 0x3) + 1)) - 1)
<< (~RF.StackAdjust() & 0x3));
return std::make_pair(GPRMask, VFPMask);
}
} // namespace WinEH
} // namespace ARM
} // namespace llvm