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 #ifndef LIBABCKIT_SRC_IR_BUILDER_DYNAMIC_BYTECODE_INST_INL_H
17 #define LIBABCKIT_SRC_IR_BUILDER_DYNAMIC_BYTECODE_INST_INL_H
18
19 #include "libabckit/src/irbuilder_dynamic/bytecode_inst.h"
20 #include "libabckit/src/macros.h"
21
22 namespace libabckit {
23
24 template <class R, class S>
25 // CC-OFFNXT(G.FUD.06) perf critical
ReadHelper(size_t byteoffset,size_t bytecount,size_t offset,size_t width)26 inline auto BytecodeInst::ReadHelper(size_t byteoffset, size_t bytecount, size_t offset, size_t width) const
27 {
28 constexpr size_t BYTE_WIDTH = 8;
29
30 size_t rightShift = offset % BYTE_WIDTH;
31
32 S v = 0;
33 for (size_t i = 0; i < bytecount; i++) {
34 S mask = static_cast<S>(ReadByte(byteoffset + i)) << (i * BYTE_WIDTH);
35 v |= mask;
36 }
37
38 v >>= rightShift;
39 size_t leftShift = sizeof(R) * BYTE_WIDTH - width;
40
41 // Do sign extension using arithmetic shift. It's implementation defined
42 // so we check such behavior using static assert
43 // NOLINTNEXTLINE(hicpp-signed-bitwise)
44 static_assert((-1 >> 1) == -1);
45
46 // NOLINTNEXTLINE(hicpp-signed-bitwise)
47 return static_cast<R>(v << leftShift) >> leftShift;
48 }
49
50 // IS_SIGNED = false
51 template <size_t OFFSET, size_t WIDTH, bool IS_SIGNED>
Read()52 inline auto BytecodeInst::Read() const
53 {
54 constexpr size_t BYTE_WIDTH = 8;
55 constexpr size_t BYTE_OFFSET = OFFSET / BYTE_WIDTH;
56 constexpr size_t BYTE_OFFSET_END = (OFFSET + WIDTH + BYTE_WIDTH - 1) / BYTE_WIDTH;
57 constexpr size_t BYTE_COUNT = BYTE_OFFSET_END - BYTE_OFFSET;
58
59 using StorageType = ark::helpers::TypeHelperT<BYTE_COUNT * BYTE_WIDTH, false>;
60 using ReturnType = ark::helpers::TypeHelperT<WIDTH, IS_SIGNED>;
61
62 return ReadHelper<ReturnType, StorageType>(BYTE_OFFSET, BYTE_COUNT, OFFSET, WIDTH);
63 }
64
65 // IS_SIGNED = false
66 template <bool IS_SIGNED>
Read64(size_t offset,size_t width)67 inline auto BytecodeInst::Read64(size_t offset, size_t width) const
68 {
69 constexpr size_t BIT64 = 64;
70 constexpr size_t BYTE_WIDTH = 8;
71
72 ASSERT((offset % BYTE_WIDTH) + width <= BIT64);
73
74 size_t byteoffset = offset / BYTE_WIDTH;
75 size_t byteoffsetEnd = (offset + width + BYTE_WIDTH - 1) / BYTE_WIDTH;
76 size_t bytecount = byteoffsetEnd - byteoffset;
77
78 using StorageType = ark::helpers::TypeHelperT<BIT64, false>;
79 using ReturnType = ark::helpers::TypeHelperT<BIT64, IS_SIGNED>;
80
81 return ReadHelper<ReturnType, StorageType>(byteoffset, bytecount, offset, width);
82 }
83
GetSize()84 inline size_t BytecodeInst::GetSize() const
85 {
86 return Size(GetFormat());
87 }
88
89 #include <generated/bytecode_inst-inl_gen.h>
90
91 } // namespace libabckit
92
93 #endif // LIBABCKIT_SRC_IR_BUILDER_DYNAMIC_BYTECODE_INST_INL_H
94