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 16 #ifndef COMPILER_CODE_INFO_VREG_INFO_H 17 #define COMPILER_CODE_INFO_VREG_INFO_H 18 19 #include "utils/bit_field.h" 20 21 namespace panda::compiler { 22 23 class VRegInfo final { 24 public: 25 enum class Location : int8_t { NONE, SLOT, REGISTER, FP_REGISTER, CONSTANT, COUNT = CONSTANT }; 26 27 static constexpr size_t INVALID_LOCATION = (1U << MinimumBitsToStore(static_cast<size_t>(Location::COUNT))) - 1; 28 29 enum class Type : uint8_t { UNDEFINED, OBJECT, INT32, INT64, FLOAT32, FLOAT64, BOOL, ANY, COUNT = ANY }; 30 VRegInfo()31 VRegInfo() 32 { 33 FieldLocation::Set(Location::NONE, &info_); 34 ASSERT(!IsLive()); 35 } VRegInfo(uint32_t value,VRegInfo::Location location,Type type,bool is_acc)36 VRegInfo(uint32_t value, VRegInfo::Location location, Type type, bool is_acc) 37 : value_(value), 38 info_(FieldLocation::Encode(location) | FieldType::Encode(type) | FieldIsAccumulator::Encode(is_acc)) 39 { 40 } VRegInfo(uint32_t value,VRegInfo::Location location,Type type,bool is_acc,uint32_t index)41 VRegInfo(uint32_t value, VRegInfo::Location location, Type type, bool is_acc, uint32_t index) 42 : VRegInfo(value, location, type, is_acc) 43 { 44 FieldVRegIndex::Set(index, &info_); 45 } VRegInfo(uint32_t value,uint32_t packed_info)46 VRegInfo(uint32_t value, uint32_t packed_info) : value_(value), info_(packed_info) {} 47 Invalid()48 static VRegInfo Invalid() 49 { 50 return VRegInfo(0, static_cast<Location>(INVALID_LOCATION), Type::UNDEFINED, false); 51 } 52 53 ~VRegInfo() = default; 54 55 DEFAULT_COPY_SEMANTIC(VRegInfo); 56 DEFAULT_MOVE_SEMANTIC(VRegInfo); 57 GetValue()58 uint32_t GetValue() const 59 { 60 return value_; 61 } 62 SetValue(uint32_t value)63 void SetValue(uint32_t value) 64 { 65 value_ = value; 66 } 67 GetLocation()68 Location GetLocation() const 69 { 70 return FieldLocation::Get(info_); 71 } 72 GetType()73 Type GetType() const 74 { 75 return FieldType::Get(info_); 76 } 77 GetIndex()78 uint16_t GetIndex() const 79 { 80 return FieldVRegIndex::Get(info_); 81 } SetIndex(uint16_t value)82 void SetIndex(uint16_t value) 83 { 84 FieldVRegIndex::Set(value, &info_); 85 } 86 IsAccumulator()87 bool IsAccumulator() const 88 { 89 return FieldIsAccumulator::Get(info_); 90 } 91 IsLive()92 bool IsLive() const 93 { 94 return GetLocation() != Location::NONE; 95 } 96 IsObject()97 bool IsObject() const 98 { 99 return GetType() == Type::OBJECT; 100 } 101 IsFloat()102 bool IsFloat() const 103 { 104 return GetType() == Type::FLOAT32 || GetType() == Type::FLOAT64; 105 } 106 Has64BitValue()107 bool Has64BitValue() const 108 { 109 return GetType() == VRegInfo::Type::FLOAT64 || GetType() == VRegInfo::Type::INT64; 110 } 111 IsLocationRegister()112 bool IsLocationRegister() const 113 { 114 auto location = GetLocation(); 115 return location == Location::REGISTER || location == Location::FP_REGISTER; 116 } 117 GetConstantLowIndex()118 uint32_t GetConstantLowIndex() const 119 { 120 ASSERT(GetLocation() == Location::CONSTANT); 121 return GetValue() & ((1U << BITS_PER_UINT16) - 1); 122 } 123 GetConstantHiIndex()124 uint32_t GetConstantHiIndex() const 125 { 126 ASSERT(GetLocation() == Location::CONSTANT); 127 return (GetValue() >> BITS_PER_UINT16) & ((1U << BITS_PER_UINT16) - 1); 128 } 129 SetConstantIndices(uint16_t low,uint16_t hi)130 void SetConstantIndices(uint16_t low, uint16_t hi) 131 { 132 value_ = low | (static_cast<uint32_t>(hi) << BITS_PER_UINT16); 133 } 134 135 bool operator==(const VRegInfo &rhs) const 136 { 137 return value_ == rhs.value_ && info_ == rhs.info_; 138 } 139 bool operator!=(const VRegInfo &rhs) const 140 { 141 return !(*this == rhs); 142 } 143 GetInfo()144 uint32_t GetInfo() 145 { 146 return info_; 147 } 148 GetTypeString()149 const char *GetTypeString() const 150 { 151 switch (GetType()) { 152 case Type::OBJECT: 153 return "OBJECT"; 154 case Type::INT64: 155 return "INT64"; 156 case Type::INT32: 157 return "INT32"; 158 case Type::FLOAT32: 159 return "FLOAT32"; 160 case Type::FLOAT64: 161 return "FLOAT64"; 162 case Type::BOOL: 163 return "BOOL"; 164 case Type::ANY: 165 return "ANY"; 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::compiler 219 220 #endif // COMPILER_CODE_INFO_VREG_INFO_H 221