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_x86.h" 18 19 #include "globals.h" 20 21 namespace art { 22 namespace x86 { 23 24 // Define register pairs. 25 // This list must be kept in sync with the RegisterPair enum. 26 #define REGISTER_PAIR_LIST(P) \ 27 P(EAX, EDX) \ 28 P(EAX, ECX) \ 29 P(EAX, EBX) \ 30 P(EAX, EDI) \ 31 P(EDX, ECX) \ 32 P(EDX, EBX) \ 33 P(EDX, EDI) \ 34 P(ECX, EBX) \ 35 P(ECX, EDI) \ 36 P(EBX, EDI) \ 37 P(ECX, EDX) 38 39 40 struct RegisterPairDescriptor { 41 RegisterPair reg; // Used to verify that the enum is in sync. 42 Register low; 43 Register high; 44 }; 45 46 47 static const RegisterPairDescriptor kRegisterPairs[] = { 48 #define REGISTER_PAIR_ENUMERATION(low, high) { low##_##high, low, high }, 49 REGISTER_PAIR_LIST(REGISTER_PAIR_ENUMERATION) 50 #undef REGISTER_PAIR_ENUMERATION 51 }; 52 53 std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) { 54 if (reg == kNoRegisterPair) { 55 os << "kNoRegisterPair"; 56 } else { 57 os << X86ManagedRegister::FromRegisterPair(reg); 58 } 59 return os; 60 } 61 62 bool X86ManagedRegister::Overlaps(const X86ManagedRegister& other) const { 63 if (IsNoRegister() || other.IsNoRegister()) return false; 64 CHECK(IsValidManagedRegister()); 65 CHECK(other.IsValidManagedRegister()); 66 if (Equals(other)) return true; 67 if (IsRegisterPair()) { 68 Register low = AsRegisterPairLow(); 69 Register high = AsRegisterPairHigh(); 70 return X86ManagedRegister::FromCpuRegister(low).Overlaps(other) || 71 X86ManagedRegister::FromCpuRegister(high).Overlaps(other); 72 } 73 if (other.IsRegisterPair()) { 74 return other.Overlaps(*this); 75 } 76 return false; 77 } 78 79 80 int X86ManagedRegister::AllocIdLow() const { 81 CHECK(IsRegisterPair()); 82 const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 83 kNumberOfX87RegIds); 84 CHECK_EQ(r, kRegisterPairs[r].reg); 85 return kRegisterPairs[r].low; 86 } 87 88 89 int X86ManagedRegister::AllocIdHigh() const { 90 CHECK(IsRegisterPair()); 91 const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 92 kNumberOfX87RegIds); 93 CHECK_EQ(r, kRegisterPairs[r].reg); 94 return kRegisterPairs[r].high; 95 } 96 97 98 void X86ManagedRegister::Print(std::ostream& os) const { 99 if (!IsValidManagedRegister()) { 100 os << "No Register"; 101 } else if (IsXmmRegister()) { 102 os << "XMM: " << AsXmmRegister(); 103 } else if (IsX87Register()) { 104 os << "X87: " << AsX87Register(); 105 } else if (IsCpuRegister()) { 106 os << "CPU: " << AsCpuRegister(); 107 } else if (IsRegisterPair()) { 108 os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh(); 109 } else { 110 os << "??: " << RegId(); 111 } 112 } 113 114 std::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg) { 115 reg.Print(os); 116 return os; 117 } 118 119 } // namespace x86 120 } // namespace art 121