xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp (revision 4824e7fd18a1223177218d4aec1b3c6c5c4a444e)
10b57cec5SDimitry Andric //===-- ARMMachineFunctionInfo.cpp - ARM machine function info ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "ARMMachineFunctionInfo.h"
100b57cec5SDimitry Andric #include "ARMSubtarget.h"
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric using namespace llvm;
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric void ARMFunctionInfo::anchor() {}
150b57cec5SDimitry Andric 
16*4824e7fdSDimitry Andric static bool GetBranchTargetEnforcement(MachineFunction &MF) {
17*4824e7fdSDimitry Andric   const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
18*4824e7fdSDimitry Andric   if (!Subtarget.isMClass() || !Subtarget.hasV7Ops())
19*4824e7fdSDimitry Andric     return false;
20*4824e7fdSDimitry Andric 
21*4824e7fdSDimitry Andric   const Function &F = MF.getFunction();
22*4824e7fdSDimitry Andric   if (!F.hasFnAttribute("branch-target-enforcement")) {
23*4824e7fdSDimitry Andric     if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
24*4824e7fdSDimitry Andric             F.getParent()->getModuleFlag("branch-target-enforcement")))
25*4824e7fdSDimitry Andric       return BTE->getZExtValue();
26*4824e7fdSDimitry Andric     return false;
27*4824e7fdSDimitry Andric   }
28*4824e7fdSDimitry Andric 
29*4824e7fdSDimitry Andric   const StringRef BTIEnable =
30*4824e7fdSDimitry Andric       F.getFnAttribute("branch-target-enforcement").getValueAsString();
31*4824e7fdSDimitry Andric   assert(BTIEnable.equals_insensitive("true") ||
32*4824e7fdSDimitry Andric          BTIEnable.equals_insensitive("false"));
33*4824e7fdSDimitry Andric   return BTIEnable.equals_insensitive("true");
34*4824e7fdSDimitry Andric }
35*4824e7fdSDimitry Andric 
36*4824e7fdSDimitry Andric // The pair returns values for the ARMFunctionInfo members
37*4824e7fdSDimitry Andric // SignReturnAddress and SignReturnAddressAll respectively.
38*4824e7fdSDimitry Andric static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
39*4824e7fdSDimitry Andric   if (!F.hasFnAttribute("sign-return-address")) {
40*4824e7fdSDimitry Andric     const Module &M = *F.getParent();
41*4824e7fdSDimitry Andric     if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
42*4824e7fdSDimitry Andric             M.getModuleFlag("sign-return-address"))) {
43*4824e7fdSDimitry Andric       if (Sign->getZExtValue()) {
44*4824e7fdSDimitry Andric         if (const auto *All = mdconst::extract_or_null<ConstantInt>(
45*4824e7fdSDimitry Andric                 M.getModuleFlag("sign-return-address-all")))
46*4824e7fdSDimitry Andric           return {true, All->getZExtValue()};
47*4824e7fdSDimitry Andric         return {true, false};
48*4824e7fdSDimitry Andric       }
49*4824e7fdSDimitry Andric     }
50*4824e7fdSDimitry Andric     return {false, false};
51*4824e7fdSDimitry Andric   }
52*4824e7fdSDimitry Andric 
53*4824e7fdSDimitry Andric   StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
54*4824e7fdSDimitry Andric   if (Scope.equals("none"))
55*4824e7fdSDimitry Andric     return {false, false};
56*4824e7fdSDimitry Andric 
57*4824e7fdSDimitry Andric   if (Scope.equals("all"))
58*4824e7fdSDimitry Andric     return {true, true};
59*4824e7fdSDimitry Andric 
60*4824e7fdSDimitry Andric   assert(Scope.equals("non-leaf"));
61*4824e7fdSDimitry Andric   return {true, false};
62*4824e7fdSDimitry Andric }
63*4824e7fdSDimitry Andric 
640b57cec5SDimitry Andric ARMFunctionInfo::ARMFunctionInfo(MachineFunction &MF)
650b57cec5SDimitry Andric     : isThumb(MF.getSubtarget<ARMSubtarget>().isThumb()),
665ffd83dbSDimitry Andric       hasThumb2(MF.getSubtarget<ARMSubtarget>().hasThumb2()),
675ffd83dbSDimitry Andric       IsCmseNSEntry(MF.getFunction().hasFnAttribute("cmse_nonsecure_entry")),
68*4824e7fdSDimitry Andric       IsCmseNSCall(MF.getFunction().hasFnAttribute("cmse_nonsecure_call")),
69*4824e7fdSDimitry Andric       BranchTargetEnforcement(GetBranchTargetEnforcement(MF)) {
70*4824e7fdSDimitry Andric 
71*4824e7fdSDimitry Andric   const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
72*4824e7fdSDimitry Andric   if (Subtarget.isMClass() && Subtarget.hasV7Ops())
73*4824e7fdSDimitry Andric     std::tie(SignReturnAddress, SignReturnAddressAll) =
74*4824e7fdSDimitry Andric         GetSignReturnAddress(MF.getFunction());
75*4824e7fdSDimitry Andric }
76