managed_register_arm.h revision 7a99c11d220ec68c208b507570e3a78c2c18a7a1
1// Copyright 2011 Google Inc. All Rights Reserved. 2 3#ifndef ART_SRC_MANAGED_REGISTER_ARM_H_ 4#define ART_SRC_MANAGED_REGISTER_ARM_H_ 5 6#include "constants.h" 7#include "logging.h" 8 9namespace art { 10 11// Values for register pairs. 12enum RegisterPair { 13 R0_R1 = 0, 14 R2_R3 = 1, 15 R4_R5 = 2, 16 R6_R7 = 3, 17 R1_R2 = 4, // Dalvik style passing 18 kNumberOfRegisterPairs = 5, 19 kNoRegisterPair = -1, 20}; 21 22std::ostream& operator<<(std::ostream& os, const RegisterPair& reg); 23 24const int kNumberOfCoreRegIds = kNumberOfCoreRegisters; 25const int kNumberOfCoreAllocIds = kNumberOfCoreRegisters; 26 27const int kNumberOfSRegIds = kNumberOfSRegisters; 28const int kNumberOfSAllocIds = kNumberOfSRegisters; 29 30const int kNumberOfDRegIds = kNumberOfDRegisters; 31const int kNumberOfOverlappingDRegIds = kNumberOfOverlappingDRegisters; 32const int kNumberOfDAllocIds = kNumberOfDRegIds - kNumberOfOverlappingDRegIds; 33 34const int kNumberOfPairRegIds = kNumberOfRegisterPairs; 35 36const int kNumberOfRegIds = kNumberOfCoreRegIds + kNumberOfSRegIds + 37 kNumberOfDRegIds + kNumberOfPairRegIds; 38const int kNumberOfAllocIds = 39 kNumberOfCoreAllocIds + kNumberOfSAllocIds + kNumberOfDAllocIds; 40 41// Register ids map: 42// [0..R[ core registers (enum Register) 43// [R..S[ single precision VFP registers (enum SRegister) 44// [S..D[ double precision VFP registers (enum DRegister) 45// [D..P[ core register pairs (enum RegisterPair) 46// where 47// R = kNumberOfCoreRegIds 48// S = R + kNumberOfSRegIds 49// D = S + kNumberOfDRegIds 50// P = D + kNumberOfRegisterPairs 51 52// Allocation ids map: 53// [0..R[ core registers (enum Register) 54// [R..S[ single precision VFP registers (enum SRegister) 55// [S..N[ non-overlapping double precision VFP registers (16-31 in enum 56// DRegister, VFPv3-D32 only) 57// where 58// R = kNumberOfCoreAllocIds 59// S = R + kNumberOfSAllocIds 60// N = S + kNumberOfDAllocIds 61 62 63// An instance of class 'ManagedRegister' represents a single ARM register or a 64// pair of core ARM registers (enum RegisterPair). A single register is either a 65// core register (enum Register), a VFP single precision register 66// (enum SRegister), or a VFP double precision register (enum DRegister). 67// 'ManagedRegister::NoRegister()' returns an invalid ManagedRegister. 68// There is a one-to-one mapping between ManagedRegister and register id. 69class ManagedRegister { 70 public: 71 // ManagedRegister is a value class. There exists no method to change the 72 // internal state. We therefore allow a copy constructor and an 73 // assignment-operator. 74 ManagedRegister(const ManagedRegister& other) : id_(other.id_) { } 75 76 ManagedRegister& operator=(const ManagedRegister& other) { 77 id_ = other.id_; 78 return *this; 79 } 80 81 Register AsCoreRegister() const { 82 CHECK(IsCoreRegister()); 83 return static_cast<Register>(id_); 84 } 85 86 SRegister AsSRegister() const { 87 CHECK(IsSRegister()); 88 return static_cast<SRegister>(id_ - kNumberOfCoreRegIds); 89 } 90 91 DRegister AsDRegister() const { 92 CHECK(IsDRegister()); 93 return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfSRegIds); 94 } 95 96 SRegister AsOverlappingDRegisterLow() const { 97 CHECK(IsOverlappingDRegister()); 98 DRegister d_reg = AsDRegister(); 99 return static_cast<SRegister>(d_reg * 2); 100 } 101 102 SRegister AsOverlappingDRegisterHigh() const { 103 CHECK(IsOverlappingDRegister()); 104 DRegister d_reg = AsDRegister(); 105 return static_cast<SRegister>(d_reg * 2 + 1); 106 } 107 108 RegisterPair AsRegisterPair() const { 109 CHECK(IsRegisterPair()); 110 Register reg_low = AsRegisterPairLow(); 111 if (reg_low == R1) { 112 return R1_R2; 113 } else { 114 return static_cast<RegisterPair>(reg_low / 2); 115 } 116 } 117 118 Register AsRegisterPairLow() const { 119 CHECK(IsRegisterPair()); 120 // Appropriate mapping of register ids allows to use AllocIdLow(). 121 return FromRegId(AllocIdLow()).AsCoreRegister(); 122 } 123 124 Register AsRegisterPairHigh() const { 125 CHECK(IsRegisterPair()); 126 // Appropriate mapping of register ids allows to use AllocIdHigh(). 127 return FromRegId(AllocIdHigh()).AsCoreRegister(); 128 } 129 130 bool IsCoreRegister() const { 131 CHECK(IsValidManagedRegister()); 132 return (0 <= id_) && (id_ < kNumberOfCoreRegIds); 133 } 134 135 bool IsSRegister() const { 136 CHECK(IsValidManagedRegister()); 137 const int test = id_ - kNumberOfCoreRegIds; 138 return (0 <= test) && (test < kNumberOfSRegIds); 139 } 140 141 bool IsDRegister() const { 142 CHECK(IsValidManagedRegister()); 143 const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); 144 return (0 <= test) && (test < kNumberOfDRegIds); 145 } 146 147 // Returns true if this DRegister overlaps SRegisters. 148 bool IsOverlappingDRegister() const { 149 CHECK(IsValidManagedRegister()); 150 const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); 151 return (0 <= test) && (test < kNumberOfOverlappingDRegIds); 152 } 153 154 bool IsRegisterPair() const { 155 CHECK(IsValidManagedRegister()); 156 const int test = 157 id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds + kNumberOfDRegIds); 158 return (0 <= test) && (test < kNumberOfPairRegIds); 159 } 160 161 bool IsSameType(ManagedRegister test) const { 162 CHECK(IsValidManagedRegister() && test.IsValidManagedRegister()); 163 return 164 (IsCoreRegister() && test.IsCoreRegister()) || 165 (IsSRegister() && test.IsSRegister()) || 166 (IsDRegister() && test.IsDRegister()) || 167 (IsRegisterPair() && test.IsRegisterPair()); 168 } 169 170 bool IsNoRegister() const { 171 return id_ == kNoRegister; 172 } 173 174 // It is valid to invoke Equals on and with a NoRegister. 175 bool Equals(const ManagedRegister& other) const { 176 return id_ == other.id_; 177 } 178 179 // Returns true if the two managed-registers ('this' and 'other') overlap. 180 // Either managed-register may be the NoRegister. If both are the NoRegister 181 // then false is returned. 182 bool Overlaps(const ManagedRegister& other) const; 183 184 void Print(std::ostream& os) const; 185 186 static ManagedRegister NoRegister() { 187 return ManagedRegister(); 188 } 189 190 static ManagedRegister FromCoreRegister(Register r) { 191 CHECK_NE(r, kNoRegister); 192 return FromRegId(r); 193 } 194 195 static ManagedRegister FromSRegister(SRegister r) { 196 CHECK_NE(r, kNoSRegister); 197 return FromRegId(r + kNumberOfCoreRegIds); 198 } 199 200 static ManagedRegister FromDRegister(DRegister r) { 201 CHECK_NE(r, kNoDRegister); 202 return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfSRegIds)); 203 } 204 205 static ManagedRegister FromRegisterPair(RegisterPair r) { 206 CHECK_NE(r, kNoRegisterPair); 207 return FromRegId(r + (kNumberOfCoreRegIds + 208 kNumberOfSRegIds + kNumberOfDRegIds)); 209 } 210 211 // Return a RegisterPair consisting of Register r_low and r_low + 1. 212 static ManagedRegister FromCoreRegisterPair(Register r_low) { 213 if (r_low != R1) { // not the dalvik special case 214 CHECK_NE(r_low, kNoRegister); 215 CHECK_EQ(0, (r_low % 2)); 216 const int r = r_low / 2; 217 CHECK_LT(r, kNumberOfPairRegIds); 218 return FromRegisterPair(static_cast<RegisterPair>(r)); 219 } else { 220 return FromRegisterPair(R1_R2); 221 } 222 } 223 224 // Return a DRegister overlapping SRegister r_low and r_low + 1. 225 static ManagedRegister FromSRegisterPair(SRegister r_low) { 226 CHECK_NE(r_low, kNoSRegister); 227 CHECK_EQ(0, (r_low % 2)); 228 const int r = r_low / 2; 229 CHECK_LT(r, kNumberOfOverlappingDRegIds); 230 return FromDRegister(static_cast<DRegister>(r)); 231 } 232 233 private: 234 static const int kNoRegister = -1; 235 236 ManagedRegister() : id_(kNoRegister) { } 237 238 bool IsValidManagedRegister() const { 239 return (0 <= id_) && (id_ < kNumberOfRegIds); 240 } 241 242 int RegId() const { 243 CHECK(!IsNoRegister()); 244 return id_; 245 } 246 247 int AllocId() const { 248 CHECK(IsValidManagedRegister() && 249 !IsOverlappingDRegister() && !IsRegisterPair()); 250 int r = id_; 251 if ((kNumberOfDAllocIds > 0) && IsDRegister()) { // VFPv3-D32 only. 252 r -= kNumberOfOverlappingDRegIds; 253 } 254 CHECK_LT(r, kNumberOfAllocIds); 255 return r; 256 } 257 258 int AllocIdLow() const; 259 int AllocIdHigh() const; 260 261 static ManagedRegister FromRegId(int reg_id) { 262 ManagedRegister reg; 263 reg.id_ = reg_id; 264 CHECK(reg.IsValidManagedRegister()); 265 return reg; 266 } 267 268 int id_; 269}; 270 271std::ostream& operator<<(std::ostream& os, const ManagedRegister& reg); 272 273} // namespace art 274 275#endif // ART_SRC_MANAGED_REGISTER_ARM_H_ 276