| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "managed_register_x86.h" |
| |
| #include "base/globals.h" |
| |
| namespace art HIDDEN { |
| namespace x86 { |
| |
| // Define register pairs. |
| // This list must be kept in sync with the RegisterPair enum. |
| #define REGISTER_PAIR_LIST(P) \ |
| P(EAX, EDX) \ |
| P(EAX, ECX) \ |
| P(EAX, EBX) \ |
| P(EAX, EDI) \ |
| P(EDX, ECX) \ |
| P(EDX, EBX) \ |
| P(EDX, EDI) \ |
| P(ECX, EBX) \ |
| P(ECX, EDI) \ |
| P(EBX, EDI) \ |
| P(ECX, EDX) |
| |
| |
| struct RegisterPairDescriptor { |
| RegisterPair reg; // Used to verify that the enum is in sync. |
| Register low; |
| Register high; |
| }; |
| |
| |
| static const RegisterPairDescriptor kRegisterPairs[] = { |
| #define REGISTER_PAIR_ENUMERATION(low, high) { low##_##high, low, high }, |
| REGISTER_PAIR_LIST(REGISTER_PAIR_ENUMERATION) |
| #undef REGISTER_PAIR_ENUMERATION |
| }; |
| |
| std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) { |
| if (reg == kNoRegisterPair) { |
| os << "kNoRegisterPair"; |
| } else { |
| os << X86ManagedRegister::FromRegisterPair(reg); |
| } |
| return os; |
| } |
| |
| bool X86ManagedRegister::Overlaps(const X86ManagedRegister& other) const { |
| if (IsNoRegister() || other.IsNoRegister()) return false; |
| CHECK(IsValidManagedRegister()); |
| CHECK(other.IsValidManagedRegister()); |
| if (Equals(other)) return true; |
| if (IsRegisterPair()) { |
| Register low = AsRegisterPairLow(); |
| Register high = AsRegisterPairHigh(); |
| return X86ManagedRegister::FromCpuRegister(low).Overlaps(other) || |
| X86ManagedRegister::FromCpuRegister(high).Overlaps(other); |
| } |
| if (other.IsRegisterPair()) { |
| return other.Overlaps(*this); |
| } |
| return false; |
| } |
| |
| |
| int X86ManagedRegister::AllocIdLow() const { |
| CHECK(IsRegisterPair()); |
| const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + |
| kNumberOfX87RegIds); |
| CHECK_EQ(r, kRegisterPairs[r].reg); |
| return kRegisterPairs[r].low; |
| } |
| |
| |
| int X86ManagedRegister::AllocIdHigh() const { |
| CHECK(IsRegisterPair()); |
| const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + |
| kNumberOfX87RegIds); |
| CHECK_EQ(r, kRegisterPairs[r].reg); |
| return kRegisterPairs[r].high; |
| } |
| |
| |
| void X86ManagedRegister::Print(std::ostream& os) const { |
| if (!IsValidManagedRegister()) { |
| os << "No Register"; |
| } else if (IsXmmRegister()) { |
| os << "XMM: " << AsXmmRegister(); |
| } else if (IsX87Register()) { |
| os << "X87: " << AsX87Register(); |
| } else if (IsCpuRegister()) { |
| os << "CPU: " << AsCpuRegister(); |
| } else if (IsRegisterPair()) { |
| os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh(); |
| } else { |
| os << "??: " << RegId(); |
| } |
| } |
| |
| std::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg) { |
| reg.Print(os); |
| return os; |
| } |
| |
| } // namespace x86 |
| } // namespace art |