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