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