| 1 | //===-- ARMWinEH.cpp - Windows on ARM EH Support Functions ------*- C++ -*-===// |
|---|---|
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "llvm/Support/ARMWinEH.h" |
| 10 | |
| 11 | namespace llvm { |
| 12 | namespace ARM { |
| 13 | namespace WinEH { |
| 14 | std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF, |
| 15 | bool Prologue) { |
| 16 | uint8_t NumRegisters = RF.Reg(); |
| 17 | uint8_t RegistersVFP = RF.R(); |
| 18 | uint8_t LinkRegister = RF.L(); |
| 19 | uint8_t ChainedFrame = RF.C(); |
| 20 | |
| 21 | uint16_t GPRMask = (ChainedFrame << 11); |
| 22 | uint32_t VFPMask = 0; |
| 23 | |
| 24 | if (Prologue) { |
| 25 | GPRMask |= (LinkRegister << 14); |
| 26 | } else { |
| 27 | // If Ret != 0, we pop into Lr and return later |
| 28 | if (RF.Ret() != ReturnType::RT_POP) |
| 29 | GPRMask |= (LinkRegister << 14); |
| 30 | else if (!RF.H()) // If H == 0, we pop directly into Pc |
| 31 | GPRMask |= (LinkRegister << 15); |
| 32 | // else, Ret == 0 && H == 1, we pop into Pc separately afterwards |
| 33 | } |
| 34 | |
| 35 | if (RegistersVFP) |
| 36 | VFPMask |= (((1 << ((NumRegisters + 1) % 8)) - 1) << 8); |
| 37 | else |
| 38 | GPRMask |= (((1 << (NumRegisters + 1)) - 1) << 4); |
| 39 | |
| 40 | if ((PrologueFolding(RF) && Prologue) || (EpilogueFolding(RF) && !Prologue)) |
| 41 | GPRMask |= (((1 << ((RF.StackAdjust() & 0x3) + 1)) - 1) |
| 42 | << (~RF.StackAdjust() & 0x3)); |
| 43 | |
| 44 | return std::make_pair(x&: GPRMask, y&: VFPMask); |
| 45 | } |
| 46 | } // namespace WinEH |
| 47 | } // namespace ARM |
| 48 | } // namespace llvm |
| 49 | |
| 50 |