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_INTERPRETER_H 17 #define PANDA_CODEGEN_INTERPRETER_H 18 19 #include "compiler/optimizer/code_generator/codegen_native.h" 20 21 namespace panda::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 = 12; 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 frame->SetFrameSize(fl.GetFrameSize<CFrameLayout::BYTES>()); 45 frame->SetSpillsCount(fl.GetSpillsCount()); 46 47 frame->SetCallersOffset( 48 fl.GetOffset<CFrameLayout::SP, CFrameLayout::SLOTS>(fl.GetStackStartSlot() + fl.GetCallerLastSlot(false))); 49 frame->SetFpCallersOffset( 50 fl.GetOffset<CFrameLayout::SP, CFrameLayout::SLOTS>(fl.GetStackStartSlot() + fl.GetCallerLastSlot(true))); 51 frame->SetCalleesOffset( 52 -fl.GetOffset<CFrameLayout::FP, CFrameLayout::SLOTS>(fl.GetStackStartSlot() + fl.GetCalleeLastSlot(false))); 53 frame->SetFpCalleesOffset( 54 -fl.GetOffset<CFrameLayout::FP, CFrameLayout::SLOTS>(fl.GetStackStartSlot() + fl.GetCalleeLastSlot(true))); 55 56 frame->SetSetupFrame(false); 57 frame->SetSaveFrameAndLinkRegs(true); 58 frame->SetSaveUnusedCalleeRegs(true); 59 frame->SetAdjustSpReg(true); 60 61 SetFrameInfo(frame); 62 } 63 GeneratePrologue()64 void GeneratePrologue() override 65 { 66 GetEncoder()->SetFrameLayout(panda::CFrameLayout(GetGraph()->GetArch(), SPILL_SLOTS)); 67 if (GetGraph()->GetMode().IsInterpreterEntry()) { 68 ScopedDisasmPrinter printer(this, "Entrypoint Prologue"); 69 GetCallingConvention()->GenerateNativePrologue(*GetFrameInfo()); 70 } 71 } 72 GenerateEpilogue()73 void GenerateEpilogue() override {} 74 }; 75 76 } // namespace panda::compiler 77 78 #endif // PANDA_CODEGEN_INTERPRETER_H 79