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