1 /** 2 * Copyright (c) 2021-2022 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 panda::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 IntrinsicSlowPathEntry(IntrinsicInst *inst) override; 54 void IntrinsicSaveRegisters(IntrinsicInst *inst) override; 55 void IntrinsicRestoreRegisters(IntrinsicInst *inst) override; 56 57 private: IsPrologueAligned()58 bool IsPrologueAligned() const 59 { 60 return saved_registers_.CountIsEven(); 61 } 62 63 RegMask GetCallerRegistersToRestore() const; 64 65 private: 66 RegMask saved_registers_ {}; 67 VRegMask saved_fp_registers_ {}; 68 }; 69 70 } // namespace panda::compiler 71 72 #endif // PANDA_CODEGEN_ENTRYPOINT_H 73