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