12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "managed_register_x86.h" 182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 19578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h" 20b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 21b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 { 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Define register pairs. 25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// This list must be kept in sync with the RegisterPair enum. 26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#define REGISTER_PAIR_LIST(P) \ 27b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EAX, EDX) \ 28b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EAX, ECX) \ 29b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EAX, EBX) \ 30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EAX, EDI) \ 31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EDX, ECX) \ 32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EDX, EBX) \ 33b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(EDX, EDI) \ 34b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(ECX, EBX) \ 35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers P(ECX, EDI) \ 3601bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray P(EBX, EDI) \ 3701bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray P(ECX, EDX) 38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstruct RegisterPairDescriptor { 41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers RegisterPair reg; // Used to verify that the enum is in sync. 42b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register low; 43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register high; 44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstatic const RegisterPairDescriptor kRegisterPairs[] = { 48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#define REGISTER_PAIR_ENUMERATION(low, high) { low##_##high, low, high }, 49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers REGISTER_PAIR_LIST(REGISTER_PAIR_ENUMERATION) 50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#undef REGISTER_PAIR_ENUMERATION 51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const RegisterPair& reg) { 5471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray if (reg == kNoRegisterPair) { 5571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray os << "kNoRegisterPair"; 5671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray } else { 5771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray os << X86ManagedRegister::FromRegisterPair(reg); 5871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray } 59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return os; 60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRegister::Overlaps(const X86ManagedRegister& other) const { 63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (IsNoRegister() || other.IsNoRegister()) return false; 64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(other.IsValidManagedRegister()); 66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (Equals(other)) return true; 67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (IsRegisterPair()) { 68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register low = AsRegisterPairLow(); 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register high = AsRegisterPairHigh(); 702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(low).Overlaps(other) || 712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers X86ManagedRegister::FromCpuRegister(high).Overlaps(other); 72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (other.IsRegisterPair()) { 74b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return other.Overlaps(*this); 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint X86ManagedRegister::AllocIdLow() const { 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfX87RegIds); 84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(r, kRegisterPairs[r].reg); 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return kRegisterPairs[r].low; 86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint X86ManagedRegister::AllocIdHigh() const { 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfX87RegIds); 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(r, kRegisterPairs[r].reg); 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return kRegisterPairs[r].high; 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid X86ManagedRegister::Print(std::ostream& os) const { 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!IsValidManagedRegister()) { 100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "No Register"; 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (IsXmmRegister()) { 102a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray os << "XMM: " << AsXmmRegister(); 103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (IsX87Register()) { 104a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray os << "X87: " << AsX87Register(); 105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (IsCpuRegister()) { 106a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray os << "CPU: " << AsCpuRegister(); 107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (IsRegisterPair()) { 108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh(); 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "??: " << RegId(); 111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersstd::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg) { 115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers reg.Print(os); 116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return os; 117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace x86 120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 121