• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef PANDA_INTERPRETER_ACC_VREGISTER_INL_H_
16 #define PANDA_INTERPRETER_ACC_VREGISTER_INL_H_
17 
18 #include <cstddef>
19 #include <cstdint>
20 
21 #include "runtime/interpreter/acc_vregister.h"
22 
23 #ifdef PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
24 #include "arch/global_regs.h"
25 #endif
26 
27 namespace panda::interpreter {
28 #ifdef PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
29 
30 class AccVRegisterT : public VRegisterIface<AccVRegisterT> {
31 public:
AccVRegisterT(const AccVRegister & other)32     ALWAYS_INLINE inline AccVRegisterT(const AccVRegister &other)
33     {
34         SetValue(other.GetValue());
35         SetTag(other.GetTag());
36     }
37 
AccVRegister()38     ALWAYS_INLINE inline operator AccVRegister() const
39     {
40         return AccVRegister(GetValue(), GetTag());
41     }
42 
GetValue()43     ALWAYS_INLINE inline int64_t GetValue() const
44     {
45         return arch::regs::GetAccValue();
46     }
47 
SetValue(int64_t value)48     ALWAYS_INLINE inline void SetValue(int64_t value)
49     {
50         arch::regs::SetAccValue(value);
51     }
52 
GetTag()53     ALWAYS_INLINE inline int64_t GetTag() const
54     {
55         return arch::regs::GetAccTag();
56     }
57 
SetTag(int64_t value)58     ALWAYS_INLINE inline void SetTag(int64_t value)
59     {
60         arch::regs::SetAccTag(value);
61     }
62 
63     ~AccVRegisterT() = default;
64 
65     DEFAULT_COPY_SEMANTIC(AccVRegisterT);
66     DEFAULT_MOVE_SEMANTIC(AccVRegisterT);
67 };
68 
69 template <bool is_dynamic>
70 class AccVRegisterTRef : public VRegisterRef<AccVRegisterTRef<is_dynamic>, AccVRegisterT> {
71 public:
AccVRegisterTRef(AccVRegisterT * payload)72     ALWAYS_INLINE inline explicit AccVRegisterTRef(AccVRegisterT *payload)
73         : VRegisterRef<AccVRegisterTRef<is_dynamic>, AccVRegisterT>(payload)
74     {
75     }
76 
Move(const StaticVRegisterRef & other)77     ALWAYS_INLINE inline void Move(const StaticVRegisterRef &other)
78     {
79         this->payload_->SetValue(other.GetValue());
80         this->payload_->SetTag(other.GetTag());
81     }
82 
Move(const DynamicVRegisterRef & other)83     ALWAYS_INLINE inline void Move(const DynamicVRegisterRef &other)
84     {
85         this->payload_->SetValue(other.GetValue());
86     }
87 
88     ALWAYS_INLINE inline operator std::pair<int64_t, int64_t>() const
89     {
90         return std::pair<int64_t, int64_t>(this->payload_->GetValue(), this->payload_->GetTag());
91     }
92 
93     // NOLINTNEXTLINE(bugprone-unhandled-self-assignment, cert-oop54-cpp)
94     ALWAYS_INLINE inline AccVRegisterTRef &operator=(const AccVRegisterTRef &other)
95     {
96         this->payload_->SetValue(other.GetValue());
97         this->payload_->SetTag(other.GetTag());
98         return *this;
99     }
100 
101     // NOLINTNEXTLINE(bugprone-unhandled-self-assignment, cert-oop54-cpp)
102     ALWAYS_INLINE inline AccVRegisterTRef &operator=(AccVRegisterTRef &&other)
103     {
104         this->payload_->SetValue(other.GetValue());
105         this->payload_->SetTag(other.GetTag());
106         return *this;
107     }
108 
HasObject()109     ALWAYS_INLINE inline bool HasObject() const
110     {
111         if constexpr (is_dynamic) {
112             coretypes::TaggedValue v(this->payload_->template GetAs<uint64_t>());
113             return v.IsHeapObject();
114         }
115         return this->payload_->GetTag() == BASE::GC_OBJECT_TYPE;
116     }
117 
MovePrimitive(const AccVRegisterTRef & other)118     ALWAYS_INLINE inline void MovePrimitive(const AccVRegisterTRef &other)
119     {
120         ASSERT(!other.HasObject());
121         this->payload_->SetValue(other.payload_->GetValue());
122         if constexpr (!is_dynamic) {
123             this->payload_->SetTag(BASE::PRIMITIVE_TYPE);
124         }
125     }
126 
MoveReference(const AccVRegisterTRef & other)127     ALWAYS_INLINE inline void MoveReference(const AccVRegisterTRef &other)
128     {
129         ASSERT(other.HasObject());
130         this->payload_->SetValue(other.payload_->GetValue());
131         if constexpr (!is_dynamic) {
132             this->payload_->SetTag(BASE::GC_OBJECT_TYPE);
133         }
134     }
135 
Move(const AccVRegisterTRef & other)136     ALWAYS_INLINE inline void Move(const AccVRegisterTRef &other)
137     {
138         this->payload_->SetValue(other.payload_->GetValue());
139         if constexpr (!is_dynamic) {
140             this->payload_->SetTag(other.payload_->GetTag());
141         }
142     }
143 
SetPrimitive(int32_t value)144     ALWAYS_INLINE inline void SetPrimitive(int32_t value)
145     {
146         this->payload_->Set(value);
147         if constexpr (!is_dynamic) {
148             this->payload_->SetTag(BASE::PRIMITIVE_TYPE);
149         }
150     }
151 
SetPrimitive(int64_t value)152     ALWAYS_INLINE inline void SetPrimitive(int64_t value)
153     {
154         this->payload_->Set(value);
155         if constexpr (!is_dynamic) {
156             this->payload_->SetTag(BASE::PRIMITIVE_TYPE);
157         }
158     }
159 
SetPrimitive(float value)160     ALWAYS_INLINE inline void SetPrimitive(float value)
161     {
162         this->payload_->Set(value);
163         if constexpr (!is_dynamic) {
164             this->payload_->SetTag(BASE::PRIMITIVE_TYPE);
165         }
166     }
167 
SetPrimitive(double value)168     ALWAYS_INLINE inline void SetPrimitive(double value)
169     {
170         this->payload_->Set(value);
171         if constexpr (!is_dynamic) {
172             this->payload_->SetTag(BASE::PRIMITIVE_TYPE);
173         }
174     }
175 
SetPrimitive(uint64_t value)176     ALWAYS_INLINE inline void SetPrimitive(uint64_t value)
177     {
178         this->payload_->Set(value);
179         if constexpr (!is_dynamic) {
180             this->payload_->SetTag(BASE::PRIMITIVE_TYPE);
181         }
182     }
183 
SetReference(ObjectHeader * obj)184     ALWAYS_INLINE inline void SetReference(ObjectHeader *obj)
185     {
186         this->payload_->Set(obj);
187         if constexpr (!is_dynamic) {
188             this->payload_->SetTag(BASE::GC_OBJECT_TYPE);
189         }
190     }
191 
192     ~AccVRegisterTRef() = default;
193 
194     DEFAULT_COPY_CTOR(AccVRegisterTRef)
195     DEFAULT_MOVE_CTOR(AccVRegisterTRef)
196 
197     using BASE = VRegisterRef<AccVRegisterTRef<is_dynamic>, AccVRegisterT>;
198 };
199 
200 #else
201 
202 using AccVRegisterT = AccVRegister;
203 
204 #endif  // PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
205 }  // namespace panda::interpreter
206 
207 #endif  // PANDA_INTERPRETER_ACC_VREGISTER_INL_H_
208