• 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 #ifndef PANDA_CODEGEN_INTERPRETER_H
17 #define PANDA_CODEGEN_INTERPRETER_H
18 
19 #include "compiler/optimizer/code_generator/codegen_native.h"
20 
21 namespace ark::compiler {
22 
23 /**
24  * Code generation for functions that should be called inside interpreter
25  * Prologue and epilogue of such functions are empty, all arguments are placed in registers manually
26  */
27 class CodegenInterpreter : public CodegenNative {
28 public:
29     using CodegenNative::CodegenNative;
30 
31     /**
32      *  fix number of spill slots such that RETURN handlers are able to generate epilogue correspondent to
33      *  InterpreterEntry prologue independently from number of spill slots in handler itself.
34      *  Should be synced with spills_count_max in interpreter.irt
35      */
36     static constexpr size_t SPILL_SLOTS = 32;
37 
CreateFrameInfo()38     void CreateFrameInfo() override
39     {
40         auto &fl = GetFrameLayout();
41         auto frame = GetGraph()->GetLocalAllocator()->New<FrameInfo>(
42             FrameInfo::PositionedCallers::Encode(true) | FrameInfo::PositionedCallees::Encode(true) |
43             FrameInfo::CallersRelativeFp::Encode(false) | FrameInfo::CalleesRelativeFp::Encode(true));
44         ASSERT(frame != nullptr);
45         frame->SetFrameSize(fl.GetFrameSize<CFrameLayout::OffsetUnit::BYTES>());
46         frame->SetSpillsCount(fl.GetSpillsCount());
47 
48         frame->SetCallersOffset(fl.GetOffset<CFrameLayout::OffsetOrigin::SP, CFrameLayout::OffsetUnit::SLOTS>(
49             fl.GetStackStartSlot() + fl.GetCallerLastSlot(false)));
50         frame->SetFpCallersOffset(fl.GetOffset<CFrameLayout::OffsetOrigin::SP, CFrameLayout::OffsetUnit::SLOTS>(
51             fl.GetStackStartSlot() + fl.GetCallerLastSlot(true)));
52         frame->SetCalleesOffset(-fl.GetOffset<CFrameLayout::OffsetOrigin::FP, CFrameLayout::OffsetUnit::SLOTS>(
53             fl.GetStackStartSlot() + fl.GetCalleeLastSlot(false)));
54         frame->SetFpCalleesOffset(-fl.GetOffset<CFrameLayout::OffsetOrigin::FP, CFrameLayout::OffsetUnit::SLOTS>(
55             fl.GetStackStartSlot() + fl.GetCalleeLastSlot(true)));
56 
57         frame->SetSetupFrame(true);
58         frame->SetSaveFrameAndLinkRegs(true);
59         frame->SetSaveUnusedCalleeRegs(true);
60         frame->SetAdjustSpReg(true);
61 
62         SetFrameInfo(frame);
63     }
64 
GeneratePrologue()65     void GeneratePrologue() override
66     {
67         GetEncoder()->SetFrameLayout(ark::CFrameLayout(GetGraph()->GetArch(), SPILL_SLOTS));
68         if (GetGraph()->GetMode().IsInterpreterEntry()) {
69             ScopedDisasmPrinter printer(this, "Entrypoint Prologue");
70             GetCallingConvention()->GenerateNativePrologue(*GetFrameInfo());
71         }
72     }
73 
GenerateEpilogue()74     void GenerateEpilogue() override {}
75 
EmitTailCallIntrinsic(IntrinsicInst * inst,Reg dst,SRCREGS src)76     void EmitTailCallIntrinsic(IntrinsicInst *inst, [[maybe_unused]] Reg dst, [[maybe_unused]] SRCREGS src) override
77     {
78         auto ptr = ConvertRegister(inst->GetSrcReg(0), DataType::POINTER);  // pointer
79         GetEncoder()->EncodeJump(ptr);
80     }
81 };
82 
83 }  // namespace ark::compiler
84 
85 #endif  // PANDA_CODEGEN_INTERPRETER_H
86