14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/assembler/x64/macro_assembler_x64.h" 174514f5e3Sopenharmony_ci#include "ecmascript/js_function.h" 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 204514f5e3Sopenharmony_ciusing namespace panda::ecmascript; 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_civoid MacroAssemblerX64::Move(const StackSlotOperand &dstStackSlot, Immediate value) 234514f5e3Sopenharmony_ci{ 244514f5e3Sopenharmony_ci x64::Register baseReg = (dstStackSlot.IsFrameBase()) ? x64::rbp : x64::rsp; 254514f5e3Sopenharmony_ci x64::Operand dstOpnd(baseReg, dstStackSlot.GetOffset()); 264514f5e3Sopenharmony_ci assembler.Movabs(value.GetValue(), LOCAL_SCOPE_REGISTER); 274514f5e3Sopenharmony_ci assembler.Movq(LOCAL_SCOPE_REGISTER, dstOpnd); 284514f5e3Sopenharmony_ci} 294514f5e3Sopenharmony_ci 304514f5e3Sopenharmony_civoid MacroAssemblerX64::Move(const StackSlotOperand &dstStackSlot, 314514f5e3Sopenharmony_ci const StackSlotOperand &srcStackSlot) 324514f5e3Sopenharmony_ci{ 334514f5e3Sopenharmony_ci x64::Register dstBaseReg = (dstStackSlot.IsFrameBase()) ? x64::rbp : x64::rsp; 344514f5e3Sopenharmony_ci x64::Register srcBaseReg = (srcStackSlot.IsFrameBase()) ? x64::rbp : x64::rsp; 354514f5e3Sopenharmony_ci x64::Operand srcOpnd(srcBaseReg, srcStackSlot.GetOffset()); 364514f5e3Sopenharmony_ci x64::Operand dstOpnd(dstBaseReg, dstStackSlot.GetOffset()); 374514f5e3Sopenharmony_ci assembler.Movq(srcOpnd, LOCAL_SCOPE_REGISTER); 384514f5e3Sopenharmony_ci assembler.Movq(LOCAL_SCOPE_REGISTER, dstOpnd); 394514f5e3Sopenharmony_ci} 404514f5e3Sopenharmony_ci 414514f5e3Sopenharmony_civoid MacroAssemblerX64::Cmp(const StackSlotOperand &stackSlot, Immediate value) 424514f5e3Sopenharmony_ci{ 434514f5e3Sopenharmony_ci x64::Register baseReg = (stackSlot.IsFrameBase()) ? x64::rbp : x64::rsp; 444514f5e3Sopenharmony_ci x64::Operand opnd(baseReg, stackSlot.GetOffset()); 454514f5e3Sopenharmony_ci assembler.Movq(opnd, LOCAL_SCOPE_REGISTER); 464514f5e3Sopenharmony_ci assembler.Cmp(x64::Immediate(value.GetValue()), LOCAL_SCOPE_REGISTER); 474514f5e3Sopenharmony_ci} 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_civoid MacroAssemblerX64::Bind(JumpLabel &label) 504514f5e3Sopenharmony_ci{ 514514f5e3Sopenharmony_ci assembler.Bind(&label); 524514f5e3Sopenharmony_ci} 534514f5e3Sopenharmony_ci 544514f5e3Sopenharmony_civoid MacroAssemblerX64::Jz(JumpLabel &label) 554514f5e3Sopenharmony_ci{ 564514f5e3Sopenharmony_ci assembler.Jz(&label); 574514f5e3Sopenharmony_ci} 584514f5e3Sopenharmony_ci 594514f5e3Sopenharmony_civoid MacroAssemblerX64::Jnz(JumpLabel &label) 604514f5e3Sopenharmony_ci{ 614514f5e3Sopenharmony_ci assembler.Jnz(&label); 624514f5e3Sopenharmony_ci} 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_civoid MacroAssemblerX64::Jump(JumpLabel &label) 654514f5e3Sopenharmony_ci{ 664514f5e3Sopenharmony_ci assembler.Jmp(&label); 674514f5e3Sopenharmony_ci} 684514f5e3Sopenharmony_ci 694514f5e3Sopenharmony_civoid MacroAssemblerX64::SaveReturnRegister(const StackSlotOperand &dstStackSlot) 704514f5e3Sopenharmony_ci{ 714514f5e3Sopenharmony_ci x64::Register dstBaseReg = (dstStackSlot.IsFrameBase()) ? x64::rbp : x64::rsp; 724514f5e3Sopenharmony_ci x64::Operand dstOpnd(dstBaseReg, dstStackSlot.GetOffset()); 734514f5e3Sopenharmony_ci assembler.Movq(RETURN_REGISTER, dstOpnd); 744514f5e3Sopenharmony_ci} 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_civoid MacroAssemblerX64::MovParameterIntoParamReg(MacroParameter param, x64::Register paramReg) 774514f5e3Sopenharmony_ci{ 784514f5e3Sopenharmony_ci if (std::holds_alternative<BaselineSpecialParameter>(param)) { 794514f5e3Sopenharmony_ci auto specialParam = std::get<BaselineSpecialParameter>(param); 804514f5e3Sopenharmony_ci switch (specialParam) { 814514f5e3Sopenharmony_ci case BaselineSpecialParameter::GLUE: { 824514f5e3Sopenharmony_ci assembler.Movq(GLUE_REGISTER, paramReg); 834514f5e3Sopenharmony_ci break; 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci case BaselineSpecialParameter::PROFILE_TYPE_INFO: { 864514f5e3Sopenharmony_ci assembler.Movq(x64::Operand(x64::rbp, FUNCTION_OFFSET_FROM_SP), LOCAL_SCOPE_REGISTER); 874514f5e3Sopenharmony_ci assembler.Movq( 884514f5e3Sopenharmony_ci x64::Operand(LOCAL_SCOPE_REGISTER, JSFunction::RAW_PROFILE_TYPE_INFO_OFFSET), 894514f5e3Sopenharmony_ci LOCAL_SCOPE_REGISTER); 904514f5e3Sopenharmony_ci assembler.Movq(x64::Operand(LOCAL_SCOPE_REGISTER, ProfileTypeInfoCell::VALUE_OFFSET), paramReg); 914514f5e3Sopenharmony_ci break; 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci case BaselineSpecialParameter::SP: { 944514f5e3Sopenharmony_ci assembler.Movq(x64::rbp, paramReg); 954514f5e3Sopenharmony_ci break; 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci case BaselineSpecialParameter::HOTNESS_COUNTER: { 984514f5e3Sopenharmony_ci assembler.Movq(x64::Operand(x64::rbp, FUNCTION_OFFSET_FROM_SP), LOCAL_SCOPE_REGISTER); 994514f5e3Sopenharmony_ci assembler.Movq( 1004514f5e3Sopenharmony_ci x64::Operand(LOCAL_SCOPE_REGISTER, JSFunctionBase::METHOD_OFFSET), LOCAL_SCOPE_REGISTER); 1014514f5e3Sopenharmony_ci assembler.Movzwq(x64::Operand(LOCAL_SCOPE_REGISTER, Method::LITERAL_INFO_OFFSET), paramReg); 1024514f5e3Sopenharmony_ci break; 1034514f5e3Sopenharmony_ci } 1044514f5e3Sopenharmony_ci default: { 1054514f5e3Sopenharmony_ci std::cout << "not supported BaselineSpecialParameter currently" << std::endl; 1064514f5e3Sopenharmony_ci std::abort(); 1074514f5e3Sopenharmony_ci } 1084514f5e3Sopenharmony_ci } 1094514f5e3Sopenharmony_ci return; 1104514f5e3Sopenharmony_ci } 1114514f5e3Sopenharmony_ci if (std::holds_alternative<int8_t>(param)) { 1124514f5e3Sopenharmony_ci int16_t num = std::get<int8_t>(param); 1134514f5e3Sopenharmony_ci assembler.Movq(panda::ecmascript::x64::Immediate(static_cast<int32_t>(num)), paramReg); 1144514f5e3Sopenharmony_ci return; 1154514f5e3Sopenharmony_ci } 1164514f5e3Sopenharmony_ci if (std::holds_alternative<int16_t>(param)) { 1174514f5e3Sopenharmony_ci int16_t num = std::get<int16_t>(param); 1184514f5e3Sopenharmony_ci assembler.Movq(panda::ecmascript::x64::Immediate(static_cast<int32_t>(num)), paramReg); 1194514f5e3Sopenharmony_ci return; 1204514f5e3Sopenharmony_ci } 1214514f5e3Sopenharmony_ci if (std::holds_alternative<int32_t>(param)) { 1224514f5e3Sopenharmony_ci int32_t num = std::get<int32_t>(param); 1234514f5e3Sopenharmony_ci assembler.Movq(panda::ecmascript::x64::Immediate(num), paramReg); 1244514f5e3Sopenharmony_ci return; 1254514f5e3Sopenharmony_ci } 1264514f5e3Sopenharmony_ci if (std::holds_alternative<int64_t>(param)) { 1274514f5e3Sopenharmony_ci int64_t num = std::get<int64_t>(param); 1284514f5e3Sopenharmony_ci assembler.Movabs(num, paramReg); 1294514f5e3Sopenharmony_ci return; 1304514f5e3Sopenharmony_ci } 1314514f5e3Sopenharmony_ci if (std::holds_alternative<StackSlotOperand>(param)) { 1324514f5e3Sopenharmony_ci StackSlotOperand stackSlotOpnd = std::get<StackSlotOperand>(param); 1334514f5e3Sopenharmony_ci x64::Register dstBaseReg = (stackSlotOpnd.IsFrameBase()) ? x64::rbp : x64::rsp; 1344514f5e3Sopenharmony_ci x64::Operand paramOpnd(dstBaseReg, stackSlotOpnd.GetOffset()); 1354514f5e3Sopenharmony_ci assembler.Movq(paramOpnd, paramReg); 1364514f5e3Sopenharmony_ci return; 1374514f5e3Sopenharmony_ci } 1384514f5e3Sopenharmony_ci std::cout << "not supported other type of baseline parameters currently" << std::endl; 1394514f5e3Sopenharmony_ci std::abort(); 1404514f5e3Sopenharmony_ci} 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_civoid MacroAssemblerX64::CallBuiltin(Address funcAddress, 1434514f5e3Sopenharmony_ci const std::vector<MacroParameter> ¶meters) 1444514f5e3Sopenharmony_ci{ 1454514f5e3Sopenharmony_ci for (size_t i = 0; i < parameters.size(); ++i) { 1464514f5e3Sopenharmony_ci auto param = parameters[i]; 1474514f5e3Sopenharmony_ci if (i == PARAM_REGISTER_COUNT) { 1484514f5e3Sopenharmony_ci std::cout << "should not pass parameters on the stack" << std::endl; 1494514f5e3Sopenharmony_ci std::abort(); 1504514f5e3Sopenharmony_ci } 1514514f5e3Sopenharmony_ci MovParameterIntoParamReg(param, registerParamVec[i]); 1524514f5e3Sopenharmony_ci } 1534514f5e3Sopenharmony_ci assembler.Movabs(static_cast<uint64_t>(funcAddress), LOCAL_SCOPE_REGISTER); 1544514f5e3Sopenharmony_ci assembler.Callq(LOCAL_SCOPE_REGISTER); 1554514f5e3Sopenharmony_ci} 1564514f5e3Sopenharmony_ci 1574514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 158