1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "managed_register_mips.h" 18 19 #include "globals.h" 20 21 namespace art { 22 namespace mips { 23 24 // These core registers are never available for allocation. 25 static const Register kReservedCoreRegistersArray[] = { S0, S1 }; 26 27 // We need all registers for caching. 28 static const int kNumberOfAvailableCoreRegisters = (S7 - T0) + 1; 29 static const int kNumberOfAvailableFRegisters = kNumberOfFRegisters; 30 static const int kNumberOfAvailableDRegisters = kNumberOfDRegisters; 31 static const int kNumberOfAvailableOverlappingDRegisters = 32 kNumberOfOverlappingDRegisters; 33 static const int kNumberOfAvailableRegisterPairs = kNumberOfRegisterPairs; 34 35 bool MipsManagedRegister::Overlaps(const MipsManagedRegister& other) const { 36 if (IsNoRegister() || other.IsNoRegister()) return false; 37 CHECK(IsValidManagedRegister()); 38 CHECK(other.IsValidManagedRegister()); 39 if (Equals(other)) return true; 40 if (IsRegisterPair()) { 41 Register low = AsRegisterPairLow(); 42 Register high = AsRegisterPairHigh(); 43 return MipsManagedRegister::FromCoreRegister(low).Overlaps(other) || 44 MipsManagedRegister::FromCoreRegister(high).Overlaps(other); 45 } 46 if (IsOverlappingDRegister()) { 47 if (other.IsDRegister()) return Equals(other); 48 if (other.IsFRegister()) { 49 FRegister low = AsOverlappingDRegisterLow(); 50 FRegister high = AsOverlappingDRegisterHigh(); 51 FRegister other_freg = other.AsFRegister(); 52 return (low == other_freg) || (high == other_freg); 53 } 54 return false; 55 } 56 if (other.IsRegisterPair() || other.IsOverlappingDRegister()) { 57 return other.Overlaps(*this); 58 } 59 return false; 60 } 61 62 63 int MipsManagedRegister::AllocIdLow() const { 64 CHECK(IsOverlappingDRegister() || IsRegisterPair()); 65 const int r = RegId() - (kNumberOfCoreRegIds + kNumberOfFRegIds); 66 int low; 67 if (r < kNumberOfOverlappingDRegIds) { 68 CHECK(IsOverlappingDRegister()); 69 low = (r * 2) + kNumberOfCoreRegIds; // Return an FRegister. 70 } else { 71 CHECK(IsRegisterPair()); 72 low = (r - kNumberOfDRegIds) * 2 + 2; // Return a Register. 73 if (low >= 24) { 74 // we got a pair higher than S6_S7, must be the dalvik special case 75 low = 5; 76 } 77 } 78 return low; 79 } 80 81 82 int MipsManagedRegister::AllocIdHigh() const { 83 return AllocIdLow() + 1; 84 } 85 86 87 void MipsManagedRegister::Print(std::ostream& os) const { 88 if (!IsValidManagedRegister()) { 89 os << "No Register"; 90 } else if (IsCoreRegister()) { 91 os << "Core: " << static_cast<int>(AsCoreRegister()); 92 } else if (IsRegisterPair()) { 93 os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh(); 94 } else if (IsFRegister()) { 95 os << "FRegister: " << static_cast<int>(AsFRegister()); 96 } else if (IsDRegister()) { 97 os << "DRegister: " << static_cast<int>(AsDRegister()); 98 } else { 99 os << "??: " << RegId(); 100 } 101 } 102 103 std::ostream& operator<<(std::ostream& os, const MipsManagedRegister& reg) { 104 reg.Print(os); 105 return os; 106 } 107 108 std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) { 109 os << MipsManagedRegister::FromRegisterPair(reg); 110 return os; 111 } 112 113 } // namespace mips 114 } // namespace art 115