1 /* 2 * Copyright (c) 2021 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 PANDA_RUNTIME_VREG_INFO_H_ 17 #define PANDA_RUNTIME_VREG_INFO_H_ 18 19 #include "libpandabase/utils/bit_field.h" 20 #include "libpandabase/utils/bit_table.h" 21 #include "libpandabase/utils/small_vector.h" 22 #include "libpandabase/utils/span.h" 23 24 namespace panda { 25 26 class VRegInfo final { 27 public: 28 enum class Location : int8_t { NONE, SLOT, REGISTER, FP_REGISTER, CONSTANT, COUNT = CONSTANT, INVALID = -1 }; 29 30 enum class Type : uint8_t { UNDEFINED, OBJECT, INT32, INT64, FLOAT32, FLOAT64, BOOL, COUNT = BOOL }; 31 VRegInfo()32 VRegInfo() 33 { 34 FieldLocation::Set(Location::NONE, &info_); 35 ASSERT(!IsLive()); 36 } VRegInfo(uint32_t value,VRegInfo::Location location,Type type,bool is_acc)37 VRegInfo(uint32_t value, VRegInfo::Location location, Type type, bool is_acc) : value_(value) 38 { 39 FieldLocation::Set(location, &info_); 40 FieldType::Set(type, &info_); 41 FieldIsAccumulator ::Set(is_acc, &info_); 42 } VRegInfo(uint32_t value,VRegInfo::Location location,Type type,bool is_acc,uint32_t index)43 VRegInfo(uint32_t value, VRegInfo::Location location, Type type, bool is_acc, uint32_t index) 44 : VRegInfo(value, location, type, is_acc) 45 { 46 FieldVRegIndex::Set(index, &info_); 47 } VRegInfo(uint32_t value,uint32_t packed_info)48 VRegInfo(uint32_t value, uint32_t packed_info) : value_(value), info_(packed_info) {} 49 Invalid()50 static VRegInfo Invalid() 51 { 52 return VRegInfo(0, Location::INVALID, Type::UNDEFINED, false); 53 } 54 55 ~VRegInfo() = default; 56 57 DEFAULT_COPY_SEMANTIC(VRegInfo); 58 DEFAULT_MOVE_SEMANTIC(VRegInfo); 59 GetValue()60 uint32_t GetValue() const 61 { 62 return value_; 63 } 64 SetValue(uint32_t value)65 void SetValue(uint32_t value) 66 { 67 value_ = value; 68 } 69 GetLocation()70 Location GetLocation() const 71 { 72 return FieldLocation::Get(info_); 73 } 74 GetType()75 Type GetType() const 76 { 77 return FieldType::Get(info_); 78 } 79 GetIndex()80 uint16_t GetIndex() const 81 { 82 return FieldVRegIndex::Get(info_); 83 } SetIndex(uint16_t value)84 void SetIndex(uint16_t value) 85 { 86 FieldVRegIndex::Set(value, &info_); 87 } 88 IsAccumulator()89 bool IsAccumulator() const 90 { 91 return FieldIsAccumulator::Get(info_); 92 } 93 IsLive()94 bool IsLive() const 95 { 96 return GetLocation() != Location::NONE; 97 } 98 IsObject()99 bool IsObject() const 100 { 101 return GetType() == Type::OBJECT; 102 } 103 IsFloat()104 bool IsFloat() const 105 { 106 return GetType() == Type::FLOAT32 || GetType() == Type::FLOAT64; 107 } 108 Has64BitValue()109 bool Has64BitValue() const 110 { 111 return GetType() == VRegInfo::Type::FLOAT64 || GetType() == VRegInfo::Type::INT64; 112 } 113 IsLocationRegister()114 bool IsLocationRegister() const 115 { 116 auto location = GetLocation(); 117 return location == Location::REGISTER || location == Location::FP_REGISTER; 118 } 119 GetConstantLowIndex()120 uint32_t GetConstantLowIndex() const 121 { 122 ASSERT(GetLocation() == Location::CONSTANT); 123 return GetValue() & ((1U << BITS_PER_UINT16) - 1); 124 } 125 GetConstantHiIndex()126 uint32_t GetConstantHiIndex() const 127 { 128 ASSERT(GetLocation() == Location::CONSTANT); 129 return (GetValue() >> BITS_PER_UINT16) & ((1U << BITS_PER_UINT16) - 1); 130 } 131 SetConstantIndices(uint16_t low,uint16_t hi)132 void SetConstantIndices(uint16_t low, uint16_t hi) 133 { 134 value_ = low | (static_cast<uint32_t>(hi) << BITS_PER_UINT16); 135 } 136 137 bool operator==(const VRegInfo &rhs) const 138 { 139 return value_ == rhs.value_ && info_ == rhs.info_; 140 } 141 bool operator!=(const VRegInfo &rhs) const 142 { 143 return !(*this == rhs); 144 } 145 GetInfo()146 uint32_t GetInfo() 147 { 148 return info_; 149 } 150 GetTypeString()151 const char *GetTypeString() const 152 { 153 switch (GetType()) { 154 case Type::OBJECT: 155 return "OBJECT"; 156 case Type::INT64: 157 return "INT64"; 158 case Type::INT32: 159 return "INT32"; 160 case Type::FLOAT32: 161 return "FLOAT32"; 162 case Type::FLOAT64: 163 return "FLOAT64"; 164 case Type::BOOL: 165 return "BOOL"; 166 default: 167 break; 168 } 169 UNREACHABLE(); 170 } 171 GetLocationString()172 const char *GetLocationString() const 173 { 174 switch (GetLocation()) { 175 case Location::NONE: 176 return "NONE"; 177 case Location::SLOT: 178 return "SLOT"; 179 case Location::REGISTER: 180 return "REGISTER"; 181 case Location::FP_REGISTER: 182 return "FP_REGISTER"; 183 case Location::CONSTANT: 184 return "CONSTANT"; 185 default: 186 break; 187 } 188 UNREACHABLE(); 189 } 190 Dump(std::ostream & os)191 void Dump(std::ostream &os) const 192 { 193 os << "VReg #" << GetIndex() << ":" << GetTypeString() << ", " << GetLocationString() << "=" 194 << helpers::ToSigned(GetValue()); 195 if (IsAccumulator()) { 196 os << ", ACC"; 197 } 198 } 199 200 private: 201 uint32_t value_ {0}; 202 uint32_t info_ {0}; 203 204 using FieldLocation = BitField<Location, 0, MinimumBitsToStore(static_cast<uint32_t>(Location::COUNT))>; 205 using FieldType = FieldLocation::NextField<Type, MinimumBitsToStore(static_cast<uint32_t>(Type::COUNT))>; 206 using FieldIsAccumulator = FieldType::NextFlag; 207 using FieldVRegIndex = FieldIsAccumulator::NextField<uint16_t, BITS_PER_UINT16>; 208 }; 209 210 static_assert(sizeof(VRegInfo) <= sizeof(uint64_t)); 211 212 inline std::ostream &operator<<(std::ostream &os, const VRegInfo &vreg) 213 { 214 vreg.Dump(os); 215 return os; 216 } 217 218 } // namespace panda 219 220 #endif // PANDA_RUNTIME_VREG_INFO_H_ 221