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
Overlaps(const MipsManagedRegister & other) const35 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
AllocIdLow() const63 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
AllocIdHigh() const82 int MipsManagedRegister::AllocIdHigh() const {
83 return AllocIdLow() + 1;
84 }
85
86
Print(std::ostream & os) const87 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
operator <<(std::ostream & os,const MipsManagedRegister & reg)103 std::ostream& operator<<(std::ostream& os, const MipsManagedRegister& reg) {
104 reg.Print(os);
105 return os;
106 }
107
operator <<(std::ostream & os,const RegisterPair & reg)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