• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "codegen_native.h"
17 #include "optimizer/code_generator/method_properties.h"
18 
19 namespace ark::compiler {
20 
CreateFrameInfo()21 void CodegenNative::CreateFrameInfo()
22 {
23     auto &fl = GetFrameLayout();
24     auto frame = GetGraph()->GetLocalAllocator()->New<FrameInfo>(
25         FrameInfo::PositionedCallers::Encode(true) | FrameInfo::PositionedCallees::Encode(true) |
26         FrameInfo::CallersRelativeFp::Encode(false) | FrameInfo::CalleesRelativeFp::Encode(true));
27     ASSERT(frame != nullptr);
28     frame->SetFrameSize(fl.GetFrameSize<CFrameLayout::OffsetUnit::BYTES>());
29     frame->SetSpillsCount(fl.GetSpillsCount());
30 
31     frame->SetCallersOffset(fl.GetOffset<CFrameLayout::OffsetOrigin::SP, CFrameLayout::OffsetUnit::SLOTS>(
32         fl.GetStackStartSlot() + fl.GetCallerLastSlot(false)));
33     frame->SetFpCallersOffset(fl.GetOffset<CFrameLayout::OffsetOrigin::SP, CFrameLayout::OffsetUnit::SLOTS>(
34         fl.GetStackStartSlot() + fl.GetCallerLastSlot(true)));
35     frame->SetCalleesOffset(-fl.GetOffset<CFrameLayout::OffsetOrigin::FP, CFrameLayout::OffsetUnit::SLOTS>(
36         fl.GetStackStartSlot() + fl.GetCalleeLastSlot(false)));
37     frame->SetFpCalleesOffset(-fl.GetOffset<CFrameLayout::OffsetOrigin::FP, CFrameLayout::OffsetUnit::SLOTS>(
38         fl.GetStackStartSlot() + fl.GetCalleeLastSlot(true)));
39 
40     ASSERT(!GetGraph()->GetMethodProperties().GetRequireFrameSetup());
41     // we don't need to setup frame in native mode
42     frame->SetSetupFrame(false);
43     // we don't need to save FP and LR registers only for leaf methods
44     frame->SetSaveFrameAndLinkRegs(!GetGraph()->GetMethodProperties().IsLeaf());
45     // we may use lr reg as temp only if we saved lr in the prologue
46     if (GetTarget().SupportLinkReg()) {
47         GetEncoder()->EnableLrAsTempReg(frame->GetSaveFrameAndLinkRegs());
48     }
49     // we never need to save unused registers in native mode
50     frame->SetSaveUnusedCalleeRegs(false);
51     // we have to sub/add SP in prologue/epilogue in the following cases:
52     // - non-leaf method
53     // - leaf method and there are spills or parameters on stack
54     frame->SetAdjustSpReg(!GetGraph()->GetMethodProperties().IsLeaf() || GetGraph()->GetStackSlotsCount() != 0 ||
55                           GetGraph()->GetMethodProperties().GetHasParamsOnStack());
56     SetFrameInfo(frame);
57 }
58 
GeneratePrologue()59 void CodegenNative::GeneratePrologue()
60 {
61     SCOPED_DISASM_STR(this, "Method Prologue");
62 
63     GetCallingConvention()->GenerateNativePrologue(*GetFrameInfo());
64 
65 #if defined(EVENT_METHOD_ENTER_ENABLED) && EVENT_METHOD_ENTER_ENABLED != 0
66     MakeTrace();
67 #endif
68 }
69 
GenerateEpilogue()70 void CodegenNative::GenerateEpilogue()
71 {
72     ASSERT(GetGraph()->GetMethodProperties().IsLeaf());
73     SCOPED_DISASM_STR(this, "Method Epilogue");
74 
75 #if defined(EVENT_METHOD_EXIT_ENABLED) && EVENT_METHOD_EXIT_ENABLED != 0
76     GetCallingConvention()->GenerateNativeEpilogue(*GetFrameInfo(), MakeTrace);
77 #else
78     GetCallingConvention()->GenerateNativeEpilogue(*GetFrameInfo(), []() {});
79 #endif
80 }
81 }  // namespace ark::compiler
82