managed_register_x86.h revision 2c8f653c98d658419f464b6147c10e11a664d2e6
1b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Copyright 2011 Google Inc. All Rights Reserved.
2b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
3b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#ifndef ART_SRC_MANAGED_REGISTER_X86_H_
4b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#define ART_SRC_MANAGED_REGISTER_X86_H_
5b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
6578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "constants_x86.h"
72c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "managed_register.h"
8b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
9b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art {
102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 {
11b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
12b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Values for register pairs.
13b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// The registers in kReservedCpuRegistersArray in x86.cc are not used in pairs.
14b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// The table kRegisterPairs in x86.cc must be kept in sync with this enum.
15b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersenum RegisterPair {
16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EAX_EDX = 0,
17b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EAX_ECX = 1,
18b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EAX_EBX = 2,
19b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EAX_EDI = 3,
20b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EDX_ECX = 4,
21b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EDX_EBX = 5,
22b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EDX_EDI = 6,
23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ECX_EBX = 7,
24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ECX_EDI = 8,
25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EBX_EDI = 9,
26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  kNumberOfRegisterPairs = 10,
27b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  kNoRegisterPair = -1,
28b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers};
29b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const RegisterPair& reg);
31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCpuRegIds = kNumberOfCpuRegisters;
33b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCpuAllocIds = kNumberOfCpuRegisters;
34b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfXmmRegIds = kNumberOfXmmRegisters;
36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfXmmAllocIds = kNumberOfXmmRegisters;
37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfX87RegIds = kNumberOfX87Registers;
39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfX87AllocIds = kNumberOfX87Registers;
40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfPairRegIds = kNumberOfRegisterPairs;
42b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfRegIds = kNumberOfCpuRegIds + kNumberOfXmmRegIds +
44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    kNumberOfX87RegIds + kNumberOfPairRegIds;
45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfAllocIds = kNumberOfCpuAllocIds + kNumberOfXmmAllocIds +
46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    kNumberOfX87RegIds;
47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register ids map:
49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [0..R[  cpu registers (enum Register)
50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [R..X[  xmm registers (enum XmmRegister)
51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [X..S[  x87 registers (enum X87Register)
52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [S..P[  register pairs (enum RegisterPair)
53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where
54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   R = kNumberOfCpuRegIds
55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   X = R + kNumberOfXmmRegIds
56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   S = X + kNumberOfX87RegIds
57b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   P = X + kNumberOfRegisterPairs
58b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Allocation ids map:
60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [0..R[  cpu registers (enum Register)
61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [R..X[  xmm registers (enum XmmRegister)
62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [X..S[  x87 registers (enum X87Register)
63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where
64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   R = kNumberOfCpuRegIds
65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   X = R + kNumberOfXmmRegIds
66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   S = X + kNumberOfX87RegIds
67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// An instance of class 'ManagedRegister' represents a single cpu register (enum
70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register), an xmm register (enum XmmRegister), or a pair of cpu registers
71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// (enum RegisterPair).
72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// 'ManagedRegister::NoRegister()' provides an invalid register.
73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// There is a one-to-one mapping between ManagedRegister and register id.
742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass X86ManagedRegister : public ManagedRegister {
75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public:
76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Register AsCpuRegister() const {
77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsCpuRegister());
78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<Register>(id_);
79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  XmmRegister AsXmmRegister() const {
82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsXmmRegister());
83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<XmmRegister>(id_ - kNumberOfCpuRegIds);
84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  X87Register AsX87Register() const {
87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsX87Register());
88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<X87Register>(id_ -
89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                    (kNumberOfCpuRegIds + kNumberOfXmmRegIds));
90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Register AsRegisterPairLow() const {
93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsRegisterPair());
94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // Appropriate mapping of register ids allows to use AllocIdLow().
95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(AllocIdLow()).AsCpuRegister();
96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Register AsRegisterPairHigh() const {
99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsRegisterPair());
100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // Appropriate mapping of register ids allows to use AllocIdHigh().
101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(AllocIdHigh()).AsCpuRegister();
102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsCpuRegister() const {
105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= id_) && (id_ < kNumberOfCpuRegIds);
107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsXmmRegister() const {
110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test = id_ - kNumberOfCpuRegIds;
112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfXmmRegIds);
113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsX87Register() const {
116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds);
118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfXmmRegIds);
119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsRegisterPair() const {
122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test = id_ -
124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds);
125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfPairRegIds);
126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Print(std::ostream& os) const;
129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Returns true if the two managed-registers ('this' and 'other') overlap.
131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Either managed-register may be the NoRegister. If both are the NoRegister
132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // then false is returned.
1332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  bool Overlaps(const X86ManagedRegister& other) const;
134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static X86ManagedRegister FromCpuRegister(Register r) {
136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoRegister);
137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r);
138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static X86ManagedRegister FromXmmRegister(XmmRegister r) {
141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoXmmRegister);
142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r + kNumberOfCpuRegIds);
143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static X86ManagedRegister FromX87Register(X87Register r) {
146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoX87Register);
147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds);
148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static X86ManagedRegister FromRegisterPair(RegisterPair r) {
151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoRegisterPair);
152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                          kNumberOfX87RegIds));
154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private:
157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsValidManagedRegister() const {
158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= id_) && (id_ < kNumberOfRegIds);
159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int RegId() const {
162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(!IsNoRegister());
163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return id_;
164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int AllocId() const {
167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister() && !IsRegisterPair());
168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_LT(id_, kNumberOfAllocIds);
169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return id_;
170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int AllocIdLow() const;
173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int AllocIdHigh() const;
174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  friend class ManagedRegister;
1762c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
1772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  X86ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
1782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
1792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static X86ManagedRegister FromRegId(int reg_id) {
1802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    X86ManagedRegister reg(reg_id);
181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(reg.IsValidManagedRegister());
182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return reg;
183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers};
185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersstd::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg);
1872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
1882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace x86
1892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
1902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline x86::X86ManagedRegister ManagedRegister::AsX86() const {
1912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  x86::X86ManagedRegister reg(id_);
1922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
1932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  return reg;
1942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}
195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}  // namespace art
197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#endif  // ART_SRC_MANAGED_REGISTER_X86_H_
199