blob: 7c1f916fd0a1eadaf1289f2ecf4b08b08e95bd05 [file] [log] [blame]
Ian Rogersb033c752011-07-20 12:22:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_MANAGED_REGISTER_X86_H_
4#define ART_SRC_MANAGED_REGISTER_X86_H_
5
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07006#include "constants_x86.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -07007#include "managed_register.h"
Ian Rogersb033c752011-07-20 12:22:35 -07008
9namespace art {
Ian Rogers2c8f6532011-09-02 17:16:34 -070010namespace x86 {
Ian Rogersb033c752011-07-20 12:22:35 -070011
12// Values for register pairs.
13// The registers in kReservedCpuRegistersArray in x86.cc are not used in pairs.
14// The table kRegisterPairs in x86.cc must be kept in sync with this enum.
15enum RegisterPair {
16 EAX_EDX = 0,
17 EAX_ECX = 1,
18 EAX_EBX = 2,
19 EAX_EDI = 3,
20 EDX_ECX = 4,
21 EDX_EBX = 5,
22 EDX_EDI = 6,
23 ECX_EBX = 7,
24 ECX_EDI = 8,
25 EBX_EDI = 9,
26 kNumberOfRegisterPairs = 10,
27 kNoRegisterPair = -1,
28};
29
30std::ostream& operator<<(std::ostream& os, const RegisterPair& reg);
31
32const int kNumberOfCpuRegIds = kNumberOfCpuRegisters;
33const int kNumberOfCpuAllocIds = kNumberOfCpuRegisters;
34
35const int kNumberOfXmmRegIds = kNumberOfXmmRegisters;
36const int kNumberOfXmmAllocIds = kNumberOfXmmRegisters;
37
38const int kNumberOfX87RegIds = kNumberOfX87Registers;
39const int kNumberOfX87AllocIds = kNumberOfX87Registers;
40
41const int kNumberOfPairRegIds = kNumberOfRegisterPairs;
42
43const int kNumberOfRegIds = kNumberOfCpuRegIds + kNumberOfXmmRegIds +
44 kNumberOfX87RegIds + kNumberOfPairRegIds;
45const int kNumberOfAllocIds = kNumberOfCpuAllocIds + kNumberOfXmmAllocIds +
46 kNumberOfX87RegIds;
47
48// Register ids map:
49// [0..R[ cpu registers (enum Register)
50// [R..X[ xmm registers (enum XmmRegister)
51// [X..S[ x87 registers (enum X87Register)
52// [S..P[ register pairs (enum RegisterPair)
53// where
54// R = kNumberOfCpuRegIds
55// X = R + kNumberOfXmmRegIds
56// S = X + kNumberOfX87RegIds
57// P = X + kNumberOfRegisterPairs
58
59// Allocation ids map:
60// [0..R[ cpu registers (enum Register)
61// [R..X[ xmm registers (enum XmmRegister)
62// [X..S[ x87 registers (enum X87Register)
63// where
64// R = kNumberOfCpuRegIds
65// X = R + kNumberOfXmmRegIds
66// S = X + kNumberOfX87RegIds
67
68
69// An instance of class 'ManagedRegister' represents a single cpu register (enum
70// Register), an xmm register (enum XmmRegister), or a pair of cpu registers
71// (enum RegisterPair).
72// 'ManagedRegister::NoRegister()' provides an invalid register.
73// There is a one-to-one mapping between ManagedRegister and register id.
Ian Rogers2c8f6532011-09-02 17:16:34 -070074class X86ManagedRegister : public ManagedRegister {
Ian Rogersb033c752011-07-20 12:22:35 -070075 public:
Ian Rogersb033c752011-07-20 12:22:35 -070076 Register AsCpuRegister() const {
77 CHECK(IsCpuRegister());
78 return static_cast<Register>(id_);
79 }
80
81 XmmRegister AsXmmRegister() const {
82 CHECK(IsXmmRegister());
83 return static_cast<XmmRegister>(id_ - kNumberOfCpuRegIds);
84 }
85
86 X87Register AsX87Register() const {
87 CHECK(IsX87Register());
88 return static_cast<X87Register>(id_ -
89 (kNumberOfCpuRegIds + kNumberOfXmmRegIds));
90 }
91
92 Register AsRegisterPairLow() const {
93 CHECK(IsRegisterPair());
94 // Appropriate mapping of register ids allows to use AllocIdLow().
95 return FromRegId(AllocIdLow()).AsCpuRegister();
96 }
97
98 Register AsRegisterPairHigh() const {
99 CHECK(IsRegisterPair());
100 // Appropriate mapping of register ids allows to use AllocIdHigh().
101 return FromRegId(AllocIdHigh()).AsCpuRegister();
102 }
103
104 bool IsCpuRegister() const {
105 CHECK(IsValidManagedRegister());
106 return (0 <= id_) && (id_ < kNumberOfCpuRegIds);
107 }
108
109 bool IsXmmRegister() const {
110 CHECK(IsValidManagedRegister());
111 const int test = id_ - kNumberOfCpuRegIds;
112 return (0 <= test) && (test < kNumberOfXmmRegIds);
113 }
114
115 bool IsX87Register() const {
116 CHECK(IsValidManagedRegister());
117 const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds);
118 return (0 <= test) && (test < kNumberOfXmmRegIds);
119 }
120
121 bool IsRegisterPair() const {
122 CHECK(IsValidManagedRegister());
123 const int test = id_ -
124 (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds);
125 return (0 <= test) && (test < kNumberOfPairRegIds);
126 }
127
Ian Rogersb033c752011-07-20 12:22:35 -0700128 void Print(std::ostream& os) const;
129
Ian Rogersb033c752011-07-20 12:22:35 -0700130 // Returns true if the two managed-registers ('this' and 'other') overlap.
131 // Either managed-register may be the NoRegister. If both are the NoRegister
132 // then false is returned.
Ian Rogers2c8f6532011-09-02 17:16:34 -0700133 bool Overlaps(const X86ManagedRegister& other) const;
Ian Rogersb033c752011-07-20 12:22:35 -0700134
Ian Rogers2c8f6532011-09-02 17:16:34 -0700135 static X86ManagedRegister FromCpuRegister(Register r) {
Ian Rogersb033c752011-07-20 12:22:35 -0700136 CHECK_NE(r, kNoRegister);
137 return FromRegId(r);
138 }
139
Ian Rogers2c8f6532011-09-02 17:16:34 -0700140 static X86ManagedRegister FromXmmRegister(XmmRegister r) {
Ian Rogersb033c752011-07-20 12:22:35 -0700141 CHECK_NE(r, kNoXmmRegister);
142 return FromRegId(r + kNumberOfCpuRegIds);
143 }
144
Ian Rogers2c8f6532011-09-02 17:16:34 -0700145 static X86ManagedRegister FromX87Register(X87Register r) {
Ian Rogersb033c752011-07-20 12:22:35 -0700146 CHECK_NE(r, kNoX87Register);
147 return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds);
148 }
149
Ian Rogers2c8f6532011-09-02 17:16:34 -0700150 static X86ManagedRegister FromRegisterPair(RegisterPair r) {
Ian Rogersb033c752011-07-20 12:22:35 -0700151 CHECK_NE(r, kNoRegisterPair);
152 return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
153 kNumberOfX87RegIds));
154 }
155
156 private:
Ian Rogersb033c752011-07-20 12:22:35 -0700157 bool IsValidManagedRegister() const {
158 return (0 <= id_) && (id_ < kNumberOfRegIds);
159 }
160
161 int RegId() const {
162 CHECK(!IsNoRegister());
163 return id_;
164 }
165
166 int AllocId() const {
167 CHECK(IsValidManagedRegister() && !IsRegisterPair());
168 CHECK_LT(id_, kNumberOfAllocIds);
169 return id_;
170 }
171
172 int AllocIdLow() const;
173 int AllocIdHigh() const;
174
Ian Rogers2c8f6532011-09-02 17:16:34 -0700175 friend class ManagedRegister;
176
177 X86ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
178
179 static X86ManagedRegister FromRegId(int reg_id) {
180 X86ManagedRegister reg(reg_id);
Ian Rogersb033c752011-07-20 12:22:35 -0700181 CHECK(reg.IsValidManagedRegister());
182 return reg;
183 }
Ian Rogersb033c752011-07-20 12:22:35 -0700184};
185
Ian Rogers2c8f6532011-09-02 17:16:34 -0700186std::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg);
187
188} // namespace x86
189
190inline x86::X86ManagedRegister ManagedRegister::AsX86() const {
191 x86::X86ManagedRegister reg(id_);
192 CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
193 return reg;
194}
Ian Rogersb033c752011-07-20 12:22:35 -0700195
196} // namespace art
197
198#endif // ART_SRC_MANAGED_REGISTER_X86_H_