1fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko/* 2fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Copyright (C) 2014 The Android Open Source Project 3fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * 4fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Licensed under the Apache License, Version 2.0 (the "License"); 5fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * you may not use this file except in compliance with the License. 6fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * You may obtain a copy of the License at 7fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * 8fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * http://www.apache.org/licenses/LICENSE-2.0 9fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * 10fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * Unless required by applicable law or agreed to in writing, software 11fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * distributed under the License is distributed on an "AS IS" BASIS, 12fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * See the License for the specific language governing permissions and 14fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko * limitations under the License. 15fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko */ 16fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 17fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "managed_register_x86_64.h" 18fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 19fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include "globals.h" 20fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 21fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace art { 22fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace x86_64 { 23fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 24fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko// Define register pairs. 25fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko// This list must be kept in sync with the RegisterPair enum. 26fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define REGISTER_PAIR_LIST(P) \ 27fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RAX, RDX) \ 28fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RAX, RCX) \ 29fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RAX, RBX) \ 30fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RAX, RDI) \ 31fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RDX, RCX) \ 32fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RDX, RBX) \ 33fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RDX, RDI) \ 34fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RCX, RBX) \ 35fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RCX, RDI) \ 36fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko P(RBX, RDI) 37fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 38fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 39fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkostruct RegisterPairDescriptor { 40fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko RegisterPair reg; // Used to verify that the enum is in sync. 41fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Register low; 42fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko Register high; 43fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}; 44fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 45fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 46fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkostatic const RegisterPairDescriptor kRegisterPairs[] = { 47fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#define REGISTER_PAIR_ENUMERATION(low, high) { low##_##high, low, high }, 48fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko REGISTER_PAIR_LIST(REGISTER_PAIR_ENUMERATION) 49fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#undef REGISTER_PAIR_ENUMERATION 50fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}; 51fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 52fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkostd::ostream& operator<<(std::ostream& os, const RegisterPair& reg) { 53fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko os << X86_64ManagedRegister::FromRegisterPair(reg); 54fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return os; 55fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 56fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 57fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkobool X86_64ManagedRegister::Overlaps(const X86_64ManagedRegister& other) const { 58fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko if (IsNoRegister() || other.IsNoRegister()) return false; 59fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK(IsValidManagedRegister()); 60fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK(other.IsValidManagedRegister()); 61fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko if (Equals(other)) return true; 62fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko if (IsRegisterPair()) { 63dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Register low = AsRegisterPairLow().AsRegister(); 64dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Register high = AsRegisterPairHigh().AsRegister(); 65fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return X86_64ManagedRegister::FromCpuRegister(low).Overlaps(other) || 66fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko X86_64ManagedRegister::FromCpuRegister(high).Overlaps(other); 67fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 68fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko if (other.IsRegisterPair()) { 69fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return other.Overlaps(*this); 70fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 71fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return false; 72fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 73fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 74fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 75fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoint X86_64ManagedRegister::AllocIdLow() const { 76fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK(IsRegisterPair()); 77fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 78fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko kNumberOfX87RegIds); 79fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_EQ(r, kRegisterPairs[r].reg); 80fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return kRegisterPairs[r].low; 81fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 82fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 83fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 84fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoint X86_64ManagedRegister::AllocIdHigh() const { 85fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK(IsRegisterPair()); 86fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 87fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko kNumberOfX87RegIds); 88fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko CHECK_EQ(r, kRegisterPairs[r].reg); 89fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return kRegisterPairs[r].high; 90fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 91fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 92fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 93fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkovoid X86_64ManagedRegister::Print(std::ostream& os) const { 94fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko if (!IsValidManagedRegister()) { 95fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko os << "No Register"; 96fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else if (IsXmmRegister()) { 97dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << "XMM: " << static_cast<int>(AsXmmRegister().AsFloatRegister()); 98fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else if (IsX87Register()) { 99fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko os << "X87: " << static_cast<int>(AsX87Register()); 100fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else if (IsCpuRegister()) { 101dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << "CPU: " << static_cast<int>(AsCpuRegister().AsRegister()); 102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else if (IsRegisterPair()) { 103fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh(); 104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } else { 105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko os << "??: " << RegId(); 106fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko } 107fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 108fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 109fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkostd::ostream& operator<<(std::ostream& os, const X86_64ManagedRegister& reg) { 110fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko reg.Print(os); 111fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko return os; 112fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} 113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko 114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} // namespace x86_64 115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko} // namespace art 116