1 /*
2 * Copyright (c) 2023 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 #include "ecmascript/stackmap/litecg_stackmap_type.h"
16
17 namespace panda::ecmascript::kungfu {
ConvertToLLVMStackMapInfo(std::vector<LLVMStackMapType::Pc2CallSiteInfo> & pc2StackMapsVec,std::vector<LLVMStackMapType::Pc2Deopt> & pc2DeoptInfoVec,Triple triple) const18 void LiteCGStackMapInfo::ConvertToLLVMStackMapInfo(
19 std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2StackMapsVec,
20 std::vector<LLVMStackMapType::Pc2Deopt> &pc2DeoptInfoVec, Triple triple) const
21 {
22 auto fpReg = GCStackMapRegisters::GetFpRegByTriple(triple);
23 for (const auto &callSiteInfo : pc2CallSiteInfoVec_) {
24 LLVMStackMapType::Pc2CallSiteInfo pc2CallSiteInfo;
25 for (const auto &elem : callSiteInfo) {
26 const std::vector<uint64_t> &litecgCallSiteInfo = elem.second;
27 LLVMStackMapType::CallSiteInfo llvmCallSiteInfo;
28 // parse std::vector<uint64_t>
29 for (size_t i = 0; i < litecgCallSiteInfo.size(); i += 2) { // add 2 each time for kind and value
30 uint64_t kind = litecgCallSiteInfo[i];
31 uint64_t value = litecgCallSiteInfo[i + 1];
32 if (kind == 2) { // kind is 2 means register
33 llvmCallSiteInfo.push_back(std::pair<uint16_t, uint32_t>(0xFFFFU, static_cast<int32_t>(value)));
34 } else if (kind == 1) { // stack
35 llvmCallSiteInfo.push_back(std::pair<uint16_t, uint32_t>(fpReg, static_cast<int32_t>(value)));
36 } else {
37 LOG_ECMA(FATAL) << "only stack and reigster is supported currently";
38 UNREACHABLE();
39 }
40 }
41 uintptr_t pc = static_cast<uintptr_t>(elem.first);
42 pc2CallSiteInfo[pc] = llvmCallSiteInfo;
43 }
44 pc2StackMapsVec.push_back(pc2CallSiteInfo);
45 }
46 for (const auto &deoptInfo : pc2DeoptVec_) {
47 LLVMStackMapType::Pc2Deopt pc2DeoptInfo;
48 for (const auto &elem : deoptInfo) {
49 const std::vector<uint64_t> &litecgDeoptInfo = elem.second;
50 LLVMStackMapType::DeoptInfoType llvmDeoptInfo;
51 // parse std::vector<uint64_t>
52 for (size_t i = 0; i < litecgDeoptInfo.size(); i += 3) { // add 3 each time for deoptVreg, kind and value
53 uint64_t deoptVreg = litecgDeoptInfo[i];
54 uint64_t kind = litecgDeoptInfo[i + 1];
55 uint64_t value = litecgDeoptInfo[i + 2];
56 llvmDeoptInfo.push_back(static_cast<int32_t>(deoptVreg));
57 if (kind == 2) { // kind is 2 means register
58 llvmDeoptInfo.push_back(std::pair<uint16_t, uint32_t>(0xFFFFU, static_cast<int32_t>(value)));
59 } else if (kind == 1) { // stack
60 llvmDeoptInfo.push_back(std::pair<uint16_t, uint32_t>(fpReg, static_cast<int32_t>(value)));
61 } else { // imm
62 llvmDeoptInfo.push_back(static_cast<int32_t>(value));
63 }
64 }
65 pc2DeoptInfo[elem.first] = llvmDeoptInfo;
66 }
67
68 pc2DeoptInfoVec.push_back(pc2DeoptInfo);
69 }
70 }
71 } // namespace panda::ecmascript::kungfu