• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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,bool isBaseDerivedEq)18 void LLVMStackMapType::EncodeRegAndOffset(std::vector<uint8_t> &regOffset, size_t &regOffsetSize,
19     DwarfRegType reg, OffsetType offset, Triple triple, bool isBaseDerivedEq)
20 {
21     SLeb128Type dwarfRegAndOff = offset;
22     auto fpReg = GCStackMapRegisters::GetFpRegByTriple(triple);
23     auto spReg = GCStackMapRegisters::GetSpRegByTriple(triple);
24     if (offset % STACKMAP_OFFSET_MUL != 0) {
25         LOG_ECMA(FATAL) << "offset is not multiple of 8";
26     }
27     if (reg == fpReg) {
28         dwarfRegAndOff = dwarfRegAndOff | FP_VALUE; // use last digit for fp/sp reg
29     } else if (reg == spReg) {
30         dwarfRegAndOff = dwarfRegAndOff | SP_VALUE;
31     } else {
32         LOG_ECMA(FATAL) << "dwarfreg branch is unreachable";
33         UNREACHABLE();
34     }
35     if (isBaseDerivedEq) {
36         dwarfRegAndOff |= NO_DERIVED; // use the second to last digit for base ref/has derived ref
37     }
38     size_t valueSize = panda::leb128::SignedEncodingSize(dwarfRegAndOff);
39     regOffset.resize(valueSize);
40     regOffsetSize = panda::leb128::EncodeSigned(dwarfRegAndOff, regOffset.data());
41 }
42 
IsBaseEqualDerive(SLeb128Type regOffset)43 bool LLVMStackMapType::IsBaseEqualDerive(SLeb128Type regOffset)
44 {
45     return (static_cast<uint64_t>(regOffset) & NO_DERIVED) != 0;
46 }
GetOffsetFromRegOff(SLeb128Type regOffset)47 LLVMStackMapType::OffsetType LLVMStackMapType::GetOffsetFromRegOff(SLeb128Type regOffset)
48 {
49     return static_cast<LLVMStackMapType::OffsetType>(static_cast<uint64_t>(regOffset) & STACKMAP_OFFSET_MASK);
50 }
51 
DecodeRegAndOffset(SLeb128Type regOffset,DwarfRegType & reg,OffsetType & offset)52 bool LLVMStackMapType::DecodeRegAndOffset(SLeb128Type regOffset, DwarfRegType &reg, OffsetType &offset)
53 {
54     if (regOffset % STACKMAP_TYPE_NUM == LLVMStackMapType::FP_VALUE) {
55         reg = GCStackMapRegisters::FP;
56     } else {
57         reg = GCStackMapRegisters::SP;
58     }
59 
60     // last three bits set to 0
61     offset = GetOffsetFromRegOff(regOffset);
62     ASSERT(offset % STACKMAP_OFFSET_MUL == 0);
63     return IsBaseEqualDerive(regOffset);
64 }
65 
EncodeVRegsInfo(std::vector<uint8_t> & vregsInfo,size_t & vregsInfoSize,VRegId id,LocationTy::Kind kind)66 void LLVMStackMapType::EncodeVRegsInfo(std::vector<uint8_t> &vregsInfo, size_t &vregsInfoSize,
67     VRegId id, LocationTy::Kind kind)
68 {
69     SLeb128Type vregIdAndKind = id;
70     if (kind == LocationTy::Kind::CONSTANT || kind == LocationTy::Kind::CONSTANTNDEX) {
71         vregIdAndKind = (vregIdAndKind << 1) + CONSTANT_TYPE;
72     } else if (kind == LocationTy::Kind::INDIRECT) {
73         vregIdAndKind = (vregIdAndKind << 1) + OFFSET_TYPE;
74     } else {
75         LOG_ECMA(FATAL) << "vreg kind branch is unreachable";
76         UNREACHABLE();
77     }
78     size_t vregIdAndKindSize = panda::leb128::SignedEncodingSize(vregIdAndKind);
79     vregsInfo.resize(vregIdAndKindSize);
80     vregsInfoSize = panda::leb128::EncodeSigned(vregIdAndKind, vregsInfo.data());
81 }
82 
DecodeVRegsInfo(SLeb128Type vregsInfo,VRegId & id,KindType & kind)83 void LLVMStackMapType::DecodeVRegsInfo(SLeb128Type vregsInfo, VRegId &id, KindType &kind)
84 {
85     if (vregsInfo % STACKMAP_TYPE_NUM == CONSTANT_TYPE) {
86         kind = CONSTANT_TYPE;
87     } else {
88         kind = OFFSET_TYPE;
89     }
90     id = static_cast<VRegId>(vregsInfo >> 1);
91 }
92 }  // namespace panda::ecmascript::kungfu