• 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_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> &regOffset, size_t &regOffsetSize,
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 &reg, 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