1/* 2 * Copyright (c) 2022-2024 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#include "ecmascript/compiler/assembler/aarch64/extend_assembler.h" 17 18#include "ecmascript/frames.h" 19 20namespace panda::ecmascript::aarch64 { 21Register ExtendedAssembler::ghcJSCallDispacherArgs_[JS_CALL_DISPATCHER_ARGS_COUNT] = { 22 X19, FP, X20, X21, X22, X23, X24, X25, X26 23}; 24Register ExtendedAssembler::cppJSCallDispacherArgs_[JS_CALL_DISPATCHER_ARGS_COUNT] = { 25 X0, FP, X1, X2, X3, X4, X5, X6, X7 26}; 27 28void ExtendedAssembler::CalleeSave() 29{ 30 Register sp(SP); 31 Stp(Register(X27), Register(X28), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 32 Stp(Register(X25), Register(X26), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 33 Stp(Register(X23), Register(X24), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 34 Stp(Register(X21), Register(X22), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 35 Stp(Register(X19), Register(X20), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 36 37 Stp(VectorRegister(v14), VectorRegister(v15), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 38 Stp(VectorRegister(v12), VectorRegister(v13), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 39 Stp(VectorRegister(v10), VectorRegister(v11), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 40 Stp(VectorRegister(v8), VectorRegister(v9), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 41} 42 43void ExtendedAssembler::CalleeRestore() 44{ 45 Register sp(SP); 46 Ldp(VectorRegister(v8), VectorRegister(v9), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 47 Ldp(VectorRegister(v10), VectorRegister(v11), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 48 Ldp(VectorRegister(v12), VectorRegister(v13), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 49 Ldp(VectorRegister(v14), VectorRegister(v15), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 50 Ldp(Register(X19), Register(X20), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 51 Ldp(Register(X21), Register(X22), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 52 Ldp(Register(X23), Register(X24), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 53 Ldp(Register(X25), Register(X26), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 54 Ldp(Register(X27), Register(X28), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 55} 56 57void ExtendedAssembler::CallAssemblerStub(int id, bool isTail) 58{ 59 Label *target = module_->GetFunctionLabel(id); 60 isTail ? B(target) : Bl(target); 61} 62 63void ExtendedAssembler::BindAssemblerStub(int id) 64{ 65 Label *target = module_->GetFunctionLabel(id); 66 Bind(target); 67 auto callSigns = module_->GetCSigns(); 68 auto cs = callSigns[id]; 69 isGhcCallingConv_ = cs->GetCallConv() == kungfu::CallSignature::CallConv::GHCCallConv; 70} 71 72void ExtendedAssembler::PushFpAndLr() 73{ 74 Register sp(SP); 75 Stp(Register(X29), Register(X30), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 76} 77 78void ExtendedAssembler::SaveFpAndLr() 79{ 80 Register sp(SP); 81 Stp(Register(X29), Register(X30), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 82 Mov(Register(X29), Register(SP)); 83} 84 85void ExtendedAssembler::RestoreFpAndLr() 86{ 87 Register sp(SP); 88 Ldp(Register(X29), Register(X30), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 89} 90 91void ExtendedAssembler::PushLrAndFp() 92{ 93 Register sp(SP); 94 Stp(Register(X30), Register(X29), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 95} 96 97void ExtendedAssembler::SaveLrAndFp() 98{ 99 Register sp(SP); 100 Stp(Register(X30), Register(X29), MemoryOperand(sp, -PAIR_SLOT_SIZE, PREINDEX)); 101 Mov(Register(X29), Register(SP)); 102} 103 104void ExtendedAssembler::RestoreLrAndFp() 105{ 106 Register sp(SP); 107 Ldp(Register(X30), Register(X29), MemoryOperand(sp, PAIR_SLOT_SIZE, POSTINDEX)); 108} 109 110void ExtendedAssembler::PushArgc(int32_t argc, Register op, Register fp) 111{ 112 Mov(op, Immediate(JSTaggedValue(argc).GetRawData())); 113 Str(op, MemoryOperand(fp, -8, PREINDEX)); // -8: 8 bytes 114} 115 116void ExtendedAssembler::PushArgc(Register argc, Register op, Register fp) 117{ 118 Orr(op, argc, LogicalImmediate::Create(JSTaggedValue::TAG_INT, RegXSize)); 119 Str(op, MemoryOperand(fp, -8, PREINDEX)); // -8: 8 bytes 120} 121 122void ExtendedAssembler::Align16(Register fp) 123{ 124 Label aligned; 125 Tst(fp, LogicalImmediate::Create(0xf, RegXSize)); // 0xf: 0x1111 126 B(Condition::EQ, &aligned); 127 // 8: frame slot size 128 Sub(fp, fp, Immediate(8)); 129 Bind(&aligned); 130} 131} // namespace panda::ecmascript::aarch64