blob: 45f73d6225c8ce25bd9727a82f294b998dc4a678 [file] [log] [blame]
Ian Rogersb033c752011-07-20 12:22:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Ian Rogers2c8f6532011-09-02 17:16:34 -07003#include "managed_register_x86.h"
4
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07005#include "globals.h"
6#include "calling_convention.h"
Ian Rogersb033c752011-07-20 12:22:35 -07007
8namespace art {
Ian Rogers2c8f6532011-09-02 17:16:34 -07009namespace x86 {
Ian Rogersb033c752011-07-20 12:22:35 -070010
11// These cpu registers are never available for allocation.
12static const Register kReservedCpuRegistersArray[] = { EBP, ESP };
13
14
15// We reduce the number of available registers for allocation in debug-code
16// mode in order to increase register pressure.
17
18// We need all registers for caching.
19static const int kNumberOfAvailableCpuRegisters = kNumberOfCpuRegisters;
20static const int kNumberOfAvailableXmmRegisters = kNumberOfXmmRegisters;
21static const int kNumberOfAvailableRegisterPairs = kNumberOfRegisterPairs;
22
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
38
39struct RegisterPairDescriptor {
40 RegisterPair reg; // Used to verify that the enum is in sync.
41 Register low;
42 Register high;
43};
44
45
46static const RegisterPairDescriptor kRegisterPairs[] = {
47#define REGISTER_PAIR_ENUMERATION(low, high) { low##_##high, low, high },
48 REGISTER_PAIR_LIST(REGISTER_PAIR_ENUMERATION)
49#undef REGISTER_PAIR_ENUMERATION
50};
51
52std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) {
Ian Rogers2c8f6532011-09-02 17:16:34 -070053 os << X86ManagedRegister::FromRegisterPair(reg);
Ian Rogersb033c752011-07-20 12:22:35 -070054 return os;
55}
56
Ian Rogers2c8f6532011-09-02 17:16:34 -070057bool X86ManagedRegister::Overlaps(const X86ManagedRegister& other) const {
Ian Rogersb033c752011-07-20 12:22:35 -070058 if (IsNoRegister() || other.IsNoRegister()) return false;
59 CHECK(IsValidManagedRegister());
60 CHECK(other.IsValidManagedRegister());
61 if (Equals(other)) return true;
62 if (IsRegisterPair()) {
63 Register low = AsRegisterPairLow();
64 Register high = AsRegisterPairHigh();
Ian Rogers2c8f6532011-09-02 17:16:34 -070065 return X86ManagedRegister::FromCpuRegister(low).Overlaps(other) ||
66 X86ManagedRegister::FromCpuRegister(high).Overlaps(other);
Ian Rogersb033c752011-07-20 12:22:35 -070067 }
68 if (other.IsRegisterPair()) {
69 return other.Overlaps(*this);
70 }
71 return false;
72}
73
74
Ian Rogers2c8f6532011-09-02 17:16:34 -070075int X86ManagedRegister::AllocIdLow() const {
Ian Rogersb033c752011-07-20 12:22:35 -070076 CHECK(IsRegisterPair());
77 const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
78 kNumberOfX87RegIds);
79 CHECK_EQ(r, kRegisterPairs[r].reg);
80 return kRegisterPairs[r].low;
81}
82
83
Ian Rogers2c8f6532011-09-02 17:16:34 -070084int X86ManagedRegister::AllocIdHigh() const {
Ian Rogersb033c752011-07-20 12:22:35 -070085 CHECK(IsRegisterPair());
86 const int r = RegId() - (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
87 kNumberOfX87RegIds);
88 CHECK_EQ(r, kRegisterPairs[r].reg);
89 return kRegisterPairs[r].high;
90}
91
92
Ian Rogers2c8f6532011-09-02 17:16:34 -070093void X86ManagedRegister::Print(std::ostream& os) const {
Ian Rogersb033c752011-07-20 12:22:35 -070094 if (!IsValidManagedRegister()) {
95 os << "No Register";
96 } else if (IsXmmRegister()) {
97 os << "XMM: " << static_cast<int>(AsXmmRegister());
98 } else if (IsX87Register()) {
99 os << "X87: " << static_cast<int>(AsX87Register());
100 } else if (IsCpuRegister()) {
101 os << "CPU: " << static_cast<int>(AsCpuRegister());
102 } else if (IsRegisterPair()) {
103 os << "Pair: " << AsRegisterPairLow() << ", " << AsRegisterPairHigh();
104 } else {
105 os << "??: " << RegId();
106 }
107}
108
Ian Rogers2c8f6532011-09-02 17:16:34 -0700109std::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg) {
Ian Rogersb033c752011-07-20 12:22:35 -0700110 reg.Print(os);
111 return os;
112}
113
Ian Rogers2c8f6532011-09-02 17:16:34 -0700114} // namespace x86
Ian Rogersb033c752011-07-20 12:22:35 -0700115} // namespace art