• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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     frame->SetFrameSize(fl.GetFrameSize<CFrameLayout::OffsetUnit::BYTES>());
28     frame->SetSpillsCount(fl.GetSpillsCount());
29 
30     frame->SetCallersOffset(fl.GetOffset<CFrameLayout::OffsetOrigin::SP, CFrameLayout::OffsetUnit::SLOTS>(
31         fl.GetStackStartSlot() + fl.GetCallerLastSlot(false)));
32     frame->SetFpCallersOffset(fl.GetOffset<CFrameLayout::OffsetOrigin::SP, CFrameLayout::OffsetUnit::SLOTS>(
33         fl.GetStackStartSlot() + fl.GetCallerLastSlot(true)));
34     frame->SetCalleesOffset(-fl.GetOffset<CFrameLayout::OffsetOrigin::FP, CFrameLayout::OffsetUnit::SLOTS>(
35         fl.GetStackStartSlot() + fl.GetCalleeLastSlot(false)));
36     frame->SetFpCalleesOffset(-fl.GetOffset<CFrameLayout::OffsetOrigin::FP, CFrameLayout::OffsetUnit::SLOTS>(
37         fl.GetStackStartSlot() + fl.GetCalleeLastSlot(true)));
38 
39     ASSERT(!GetGraph()->GetMethodProperties().GetRequireFrameSetup());
40     // we don't need to setup frame in native mode
41     frame->SetSetupFrame(false);
42     // we don't need to save FP and LR registers only for leaf methods
43     frame->SetSaveFrameAndLinkRegs(!GetGraph()->GetMethodProperties().IsLeaf());
44     // we may use lr reg as temp only if we saved lr in the prologue
45     if (GetTarget().SupportLinkReg()) {
46         GetEncoder()->EnableLrAsTempReg(frame->GetSaveFrameAndLinkRegs());
47     }
48     // we never need to save unused registers in native mode
49     frame->SetSaveUnusedCalleeRegs(false);
50     // we have to sub/add SP in prologue/epilogue in the following cases:
51     // - non-leaf method
52     // - leaf method and there are spills or parameters on stack
53     frame->SetAdjustSpReg(!GetGraph()->GetMethodProperties().IsLeaf() || GetGraph()->GetStackSlotsCount() != 0 ||
54                           GetGraph()->GetMethodProperties().GetHasParamsOnStack());
55     SetFrameInfo(frame);
56 }
57 
GeneratePrologue()58 void CodegenNative::GeneratePrologue()
59 {
60     SCOPED_DISASM_STR(this, "Method Prologue");
61 
62     GetCallingConvention()->GenerateNativePrologue(*GetFrameInfo());
63 
64 #if defined(EVENT_METHOD_ENTER_ENABLED) && EVENT_METHOD_ENTER_ENABLED != 0
65     MakeTrace();
66 #endif
67 }
68 
GenerateEpilogue()69 void CodegenNative::GenerateEpilogue()
70 {
71     ASSERT(GetGraph()->GetMethodProperties().IsLeaf());
72     SCOPED_DISASM_STR(this, "Method Epilogue");
73 
74 #if defined(EVENT_METHOD_EXIT_ENABLED) && EVENT_METHOD_EXIT_ENABLED != 0
75     GetCallingConvention()->GenerateNativeEpilogue(*GetFrameInfo(), MakeTrace);
76 #else
77     GetCallingConvention()->GenerateNativeEpilogue(*GetFrameInfo(), []() {});
78 #endif
79 }
80 }  // namespace ark::compiler
81