• 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_ENTRYPOINT_H
17 #define PANDA_CODEGEN_ENTRYPOINT_H
18 
19 #include "compiler/optimizer/code_generator/codegen.h"
20 
21 namespace ark::compiler {
22 
23 /**
24  * Code generation for fast paths
25  *
26  * Fast path code supports only native calls, that hasn't safepoints inside. Compiler has specific intrinsics to
27  * save/restore registers before calling native functions. These intrinsics pushes caller saved registers on the stack
28  * below the frame, hereby it change SP register. Due to this fact spill/fills aren't supported in the entrypoints mode.
29  *
30  * Compiled code(caller) saves only parameter registers.
31  * Fast path entrypoint saves only used registers, and saves all caller registers if it goes to the slow path.
32  * Slow path is invoked via code-to-runtime bridge, which forms boundary frame and saves callee registers.
33  * So, before calling the slow path we restore all modified callee registers.
34  *
35  * To call C-implemented entrypoint (slow path) we need a separate bridge, because it shouldn't save caller registers
36  * before calling slow path, since they are saved within irtoced entrypoint.
37  */
38 class CodegenFastPath : public Codegen {
39 public:
40     using Codegen::Codegen;
41 
CodegenFastPath(Graph * graph)42     explicit CodegenFastPath(Graph *graph) : Codegen(graph)
43     {
44         // We don't save LR register in a prologue, so we can't use LR as a temp register in the whole Fast Path code.
45         GetEncoder()->EnableLrAsTempReg(false);
46     }
47 
48     void GeneratePrologue() override;
49     void GenerateEpilogue() override;
50 
51     void CreateFrameInfo() override;
52 
53     void EmitSimdIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
54     void EmitReverseIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
55     void EmitMarkWordIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
56     void EmitDataMemoryBarrierFullIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
57     void EmitWriteTlabStatsSafeIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
58     void EmitExpandU8ToU16Intrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
59     void EmitAtomicByteOrIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
60     void EmitSaveOrRestoreRegsEpIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
61     void EmitTailCallIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
62     void EmitSlowPathEntryIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
63     void EmitJsCastDoubleToCharIntrinsic(IntrinsicInst *inst, Reg dst, SRCREGS src) override;
64 
65 private:
66     RegMask GetCallerRegistersToRestore() const;
67     void CreateTailCall(IntrinsicInst *inst, bool isFastpath);
68 
69 private:
70     RegMask savedRegisters_ {};
71     VRegMask savedFpRegisters_ {};
72 };
73 
74 }  // namespace ark::compiler
75 
76 #endif  // PANDA_CODEGEN_ENTRYPOINT_H
77