managed_register_x86.cc revision 834b394ee759ed31c5371d8093d7cd8cd90014a8
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// These cpu registers are never available for allocation.
25static const Register kReservedCpuRegistersArray[] = { ESP };
26
27
28// We reduce the number of available registers for allocation in debug-code
29// mode in order to increase register pressure.
30
31// We need all registers for caching.
32static const int kNumberOfAvailableCpuRegisters = kNumberOfCpuRegisters;
33static const int kNumberOfAvailableXmmRegisters = kNumberOfXmmRegisters;
34static const int kNumberOfAvailableRegisterPairs = kNumberOfRegisterPairs;
35
36
37// Define register pairs.
38// This list must be kept in sync with the RegisterPair enum.
39#define REGISTER_PAIR_LIST(P) \
40  P(EAX, EDX)                 \
41  P(EAX, ECX)                 \
42  P(EAX, EBX)                 \
43  P(EAX, EDI)                 \
44  P(EDX, ECX)                 \
45  P(EDX, EBX)                 \
46  P(EDX, EDI)                 \
47  P(ECX, EBX)                 \
48  P(ECX, EDI)                 \
49  P(EBX, EDI)
50
51
52struct RegisterPairDescriptor {
53  RegisterPair reg;  // Used to verify that the enum is in sync.
54  Register low;
55  Register high;
56};
57
58
59static const RegisterPairDescriptor kRegisterPairs[] = {
60#define REGISTER_PAIR_ENUMERATION(low, high) { low##_##high, low, high },
61  REGISTER_PAIR_LIST(REGISTER_PAIR_ENUMERATION)
62#undef REGISTER_PAIR_ENUMERATION
63};
64
65std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) {
66  os << X86ManagedRegister::FromRegisterPair(reg);
67  return os;
68}
69
70bool X86ManagedRegister::Overlaps(const X86ManagedRegister& other) const {
71  if (IsNoRegister() || other.IsNoRegister()) return false;
72  CHECK(IsValidManagedRegister());
73  CHECK(other.IsValidManagedRegister());
74  if (Equals(other)) return true;
75  if (IsRegisterPair()) {
76    Register low = AsRegisterPairLow();
77    Register high = AsRegisterPairHigh();
78    return X86ManagedRegister::FromCpuRegister(low).Overlaps(other) ||
79        X86ManagedRegister::FromCpuRegister(high).Overlaps(other);
80  }
81  if (other.IsRegisterPair()) {
82    return other.Overlaps(*this);
83  }
84  return false;
85}
86
87
88int X86ManagedRegister::AllocIdLow() const {
89  CHECK(IsRegisterPair());
90  const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
91                           kNumberOfX87RegIds);
92  CHECK_EQ(r, kRegisterPairs[r].reg);
93  return kRegisterPairs[r].low;
94}
95
96
97int X86ManagedRegister::AllocIdHigh() const {
98  CHECK(IsRegisterPair());
99  const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
100                           kNumberOfX87RegIds);
101  CHECK_EQ(r, kRegisterPairs[r].reg);
102  return kRegisterPairs[r].high;
103}
104
105
106void X86ManagedRegister::Print(std::ostream& os) const {
107  if (!IsValidManagedRegister()) {
108    os << "No Register";
109  } else if (IsXmmRegister()) {
110    os << "XMM: " << static_cast<int>(AsXmmRegister());
111  } else if (IsX87Register()) {
112    os << "X87: " << static_cast<int>(AsX87Register());
113  } else if (IsCpuRegister()) {
114    os << "CPU: " << static_cast<int>(AsCpuRegister());
115  } else if (IsRegisterPair()) {
116    os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh();
117  } else {
118    os << "??: " << RegId();
119  }
120}
121
122std::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg) {
123  reg.Print(os);
124  return os;
125}
126
127}  // namespace x86
128}  // namespace art
129