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