1/* 2 * Copyright (c) 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/baseline/baseline_assembler.h" 17#include "ecmascript/compiler/assembler/x64/macro_assembler_x64.h" 18#include "ecmascript/compiler/assembler/aarch64/macro_assembler_aarch64.h" 19 20namespace panda::ecmascript::kungfu { 21using namespace panda::ecmascript; 22BaselineAssembler::BaselineAssembler(const std::string &tripleStr) : stackOffsetDescriptor(0) 23{ 24 NativeAreaAllocator allocator; 25 Chunk chunk(&allocator); 26 if (tripleStr.compare(TARGET_X64) == 0) { 27 macroAssembler = new MacroAssemblerX64(); 28 } else if (tripleStr.compare(TARGET_AARCH64) == 0) { 29 macroAssembler = new MacroAssemblerAArch64(); 30 static_cast<MacroAssemblerAArch64*>(macroAssembler)->SetBaselineFlag(); 31 } else { 32 LOG_ECMA(FATAL) << "this branch is unreachable"; 33 UNREACHABLE(); 34 } 35}; 36 37void BaselineAssembler::Move(VirtualRegister interpreterDestReg, Immediate value) 38{ 39 StackSlotOperand stackSlotOperand(StackSlotOperand::BaseRegister::FRAME_REGISTER, 40 stackOffsetDescriptor.GetVregOffset(interpreterDestReg)); 41 42 macroAssembler->Move(stackSlotOperand, value); 43} 44 45void BaselineAssembler::Move(SpecialRegister destReg, Immediate value) 46{ 47 StackSlotOperand stackSlotOperand(StackSlotOperand::BaseRegister::FRAME_REGISTER, 48 stackOffsetDescriptor.GetSpecialRegisterOffset(destReg)); 49 50 macroAssembler->Move(stackSlotOperand, value); 51} 52 53void BaselineAssembler::Move(SpecialRegister destReg, SpecialRegister srcReg) 54{ 55 StackSlotOperand srcStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 56 stackOffsetDescriptor.GetSpecialRegisterOffset(srcReg)); 57 58 StackSlotOperand dstStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 59 stackOffsetDescriptor.GetSpecialRegisterOffset(destReg)); 60 macroAssembler->Move(dstStackSlotOpnd, srcStackSlotOpnd); 61} 62 63void BaselineAssembler::Move(VirtualRegister interpreterDestReg, VirtualRegister interpreterSrcReg) 64{ 65 StackSlotOperand srcStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 66 stackOffsetDescriptor.GetVregOffset(interpreterSrcReg)); 67 68 StackSlotOperand dstStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 69 stackOffsetDescriptor.GetVregOffset(interpreterDestReg)); 70 71 macroAssembler->Move(dstStackSlotOpnd, srcStackSlotOpnd); 72} 73 74void BaselineAssembler::Move(SpecialRegister destReg, VirtualRegister interpreterSrcReg) 75{ 76 StackSlotOperand srcStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 77 stackOffsetDescriptor.GetVregOffset(interpreterSrcReg)); 78 79 StackSlotOperand dstStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 80 stackOffsetDescriptor.GetSpecialRegisterOffset(destReg)); 81 82 macroAssembler->Move(dstStackSlotOpnd, srcStackSlotOpnd); 83} 84 85void BaselineAssembler::Move(VirtualRegister interpreterDestReg, SpecialRegister srcReg) 86{ 87 StackSlotOperand srcStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 88 stackOffsetDescriptor.GetSpecialRegisterOffset(srcReg)); 89 90 StackSlotOperand dstStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 91 stackOffsetDescriptor.GetVregOffset(interpreterDestReg)); 92 93 macroAssembler->Move(dstStackSlotOpnd, srcStackSlotOpnd); 94} 95 96void BaselineAssembler::Cmp(SpecialRegister reg, Immediate value) 97{ 98 StackSlotOperand stackSlotOperand(StackSlotOperand::BaseRegister::FRAME_REGISTER, 99 stackOffsetDescriptor.GetSpecialRegisterOffset(reg)); 100 101 macroAssembler->Cmp(stackSlotOperand, value); 102} 103 104void BaselineAssembler::SaveResultIntoAcc() 105{ 106 StackSlotOperand dstStackSlotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 107 stackOffsetDescriptor.GetSpecialRegisterOffset(SpecialRegister::ACC_REGISTER)); 108 109 macroAssembler->SaveReturnRegister(dstStackSlotOpnd); 110} 111 112void BaselineAssembler::CallBuiltin(Address funcAddress, 113 const std::vector<BaselineParameter> ¶meters) 114{ 115 std::vector<MacroParameter> macroParameters; 116 for (const auto ¶m : parameters) { 117 if (std::holds_alternative<BaselineSpecialParameter>(param)) { 118 switch (std::get<BaselineSpecialParameter>(param)) { 119 case BaselineSpecialParameter::ACC: { 120 StackSlotOperand slotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 121 stackOffsetDescriptor.GetSpecialRegisterOffset(SpecialRegister::ACC_REGISTER)); 122 macroParameters.emplace_back(slotOpnd); 123 break; 124 } 125 case BaselineSpecialParameter::ENV: { 126 StackSlotOperand slotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 127 stackOffsetDescriptor.GetSpecialRegisterOffset(SpecialRegister::ENV)); 128 macroParameters.emplace_back(slotOpnd); 129 break; 130 } 131 default: 132 macroParameters.emplace_back(std::get<BaselineSpecialParameter>(param)); 133 } 134 } else if (std::holds_alternative<int8_t>(param)) { 135 macroParameters.emplace_back(std::get<int8_t>(param)); 136 } else if (std::holds_alternative<int16_t>(param)) { 137 macroParameters.emplace_back(std::get<int16_t>(param)); 138 } else if (std::holds_alternative<int32_t>(param)) { 139 macroParameters.emplace_back(std::get<int32_t>(param)); 140 } else if (std::holds_alternative<int64_t>(param)) { 141 macroParameters.emplace_back(std::get<int64_t>(param)); 142 } else { 143 VirtualRegister vReg = std::get<VirtualRegister>(param); 144 StackSlotOperand slotOpnd(StackSlotOperand::BaseRegister::FRAME_REGISTER, 145 stackOffsetDescriptor.GetVregOffset(vReg)); 146 macroParameters.emplace_back(slotOpnd); 147 } 148 } 149 macroAssembler->CallBuiltin(funcAddress, macroParameters); 150} 151 152} // namespace panda::ecmascript::kungfu 153