1 /*
2 * Copyright (c) 2022 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/llvm_stackmap_type.h"
16
17 namespace panda::ecmascript::kungfu {
EncodeRegAndOffset(std::vector<uint8_t> & regOffset,size_t & regOffsetSize,DwarfRegType reg,OffsetType offset,Triple triple)18 void LLVMStackMapType::EncodeRegAndOffset(std::vector<uint8_t> ®Offset, size_t ®OffsetSize,
19 DwarfRegType reg, OffsetType offset, Triple triple)
20 {
21 SLeb128Type dwarfRegAndOff = offset;
22 auto fpReg = GCStackMapRegisters::GetFpRegByTriple(triple);
23 auto spReg = GCStackMapRegisters::GetSpRegByTriple(triple);
24 if (reg == fpReg) {
25 dwarfRegAndOff = (dwarfRegAndOff << 1) + FP_VALUE;
26 } else if (reg == spReg) {
27 dwarfRegAndOff = (dwarfRegAndOff << 1) + SP_VALUE;
28 } else {
29 LOG_ECMA(FATAL) << "dwarfreg branch is unreachable";
30 UNREACHABLE();
31 }
32 size_t valueSize = panda::leb128::SignedEncodingSize(dwarfRegAndOff);
33 regOffset.resize(valueSize);
34 regOffsetSize = panda::leb128::EncodeSigned(dwarfRegAndOff, regOffset.data());
35 }
36
DecodeRegAndOffset(SLeb128Type regOffset,DwarfRegType & reg,OffsetType & offset)37 void LLVMStackMapType::DecodeRegAndOffset(SLeb128Type regOffset, DwarfRegType ®, OffsetType &offset)
38 {
39 if (regOffset % STACKMAP_TYPE_NUM == LLVMStackMapType::FP_VALUE) {
40 reg = GCStackMapRegisters::FP;
41 } else {
42 reg = GCStackMapRegisters::SP;
43 }
44 offset = static_cast<LLVMStackMapType::OffsetType>(regOffset >> 1);
45 }
46
EncodeVRegsInfo(std::vector<uint8_t> & vregsInfo,size_t & vregsInfoSize,VRegId id,LocationTy::Kind kind)47 void LLVMStackMapType::EncodeVRegsInfo(std::vector<uint8_t> &vregsInfo, size_t &vregsInfoSize,
48 VRegId id, LocationTy::Kind kind)
49 {
50 SLeb128Type vregIdAndKind = id;
51 if (kind == LocationTy::Kind::CONSTANT || kind == LocationTy::Kind::CONSTANTNDEX) {
52 vregIdAndKind = (vregIdAndKind << 1) + CONSTANT_TYPE;
53 } else if (kind == LocationTy::Kind::INDIRECT) {
54 vregIdAndKind = (vregIdAndKind << 1) + OFFSET_TYPE;
55 } else {
56 LOG_ECMA(FATAL) << "vreg kind branch is unreachable";
57 UNREACHABLE();
58 }
59 size_t vregIdAndKindSize = panda::leb128::SignedEncodingSize(vregIdAndKind);
60 vregsInfo.resize(vregIdAndKindSize);
61 vregsInfoSize = panda::leb128::EncodeSigned(vregIdAndKind, vregsInfo.data());
62 }
63
DecodeVRegsInfo(SLeb128Type vregsInfo,VRegId & id,KindType & kind)64 void LLVMStackMapType::DecodeVRegsInfo(SLeb128Type vregsInfo, VRegId &id, KindType &kind)
65 {
66 if (vregsInfo % STACKMAP_TYPE_NUM == CONSTANT_TYPE) {
67 kind = CONSTANT_TYPE;
68 } else {
69 kind = OFFSET_TYPE;
70 }
71 id = static_cast<VRegId>(vregsInfo >> 1);
72 }
73 } // namespace panda::ecmascript::kungfu