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