12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
17166db04e259ca51838c311891598664deeed85adIan Rogers#ifndef ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_
18166db04e259ca51838c311891598664deeed85adIan Rogers#define ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_
19b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
210f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "constants_arm.h"
22166db04e259ca51838c311891598664deeed85adIan Rogers#include "utils/managed_register.h"
23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art {
252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm {
26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
27b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Values for register pairs.
28b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersenum RegisterPair {
29b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  R0_R1 = 0,
30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  R2_R3 = 1,
31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  R4_R5 = 2,
32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  R6_R7 = 3,
337a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  R1_R2 = 4,  // Dalvik style passing
347a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  kNumberOfRegisterPairs = 5,
35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  kNoRegisterPair = -1,
36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers};
37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const RegisterPair& reg);
39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCoreRegIds = kNumberOfCoreRegisters;
41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCoreAllocIds = kNumberOfCoreRegisters;
42b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfSRegIds = kNumberOfSRegisters;
44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfSAllocIds = kNumberOfSRegisters;
45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfDRegIds = kNumberOfDRegisters;
47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfOverlappingDRegIds = kNumberOfOverlappingDRegisters;
48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfDAllocIds = kNumberOfDRegIds - kNumberOfOverlappingDRegIds;
49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfPairRegIds = kNumberOfRegisterPairs;
51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfRegIds = kNumberOfCoreRegIds + kNumberOfSRegIds +
53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    kNumberOfDRegIds + kNumberOfPairRegIds;
54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfAllocIds =
55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    kNumberOfCoreAllocIds + kNumberOfSAllocIds + kNumberOfDAllocIds;
56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
57b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register ids map:
58b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [0..R[  core registers (enum Register)
59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [R..S[  single precision VFP registers (enum SRegister)
60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [S..D[  double precision VFP registers (enum DRegister)
61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [D..P[  core register pairs (enum RegisterPair)
62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where
63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   R = kNumberOfCoreRegIds
64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   S = R + kNumberOfSRegIds
65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   D = S + kNumberOfDRegIds
66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   P = D + kNumberOfRegisterPairs
67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Allocation ids map:
69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [0..R[  core registers (enum Register)
70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [R..S[  single precision VFP registers (enum SRegister)
71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   [S..N[  non-overlapping double precision VFP registers (16-31 in enum
72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//           DRegister, VFPv3-D32 only)
73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where
74b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   R = kNumberOfCoreAllocIds
75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   S = R + kNumberOfSAllocIds
76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers//   N = S + kNumberOfDAllocIds
77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// An instance of class 'ManagedRegister' represents a single ARM register or a
80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// pair of core ARM registers (enum RegisterPair). A single register is either a
81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// core register (enum Register), a VFP single precision register
82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// (enum SRegister), or a VFP double precision register (enum DRegister).
83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// 'ManagedRegister::NoRegister()' returns an invalid ManagedRegister.
84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// There is a one-to-one mapping between ManagedRegister and register id.
852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass ArmManagedRegister : public ManagedRegister {
86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public:
87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Register AsCoreRegister() const {
88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsCoreRegister());
89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<Register>(id_);
90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  SRegister AsSRegister() const {
93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsSRegister());
94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<SRegister>(id_ - kNumberOfCoreRegIds);
95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  DRegister AsDRegister() const {
98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsDRegister());
99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfSRegIds);
100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  SRegister AsOverlappingDRegisterLow() const {
103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsOverlappingDRegister());
104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    DRegister d_reg = AsDRegister();
105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<SRegister>(d_reg * 2);
106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  SRegister AsOverlappingDRegisterHigh() const {
109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsOverlappingDRegister());
110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    DRegister d_reg = AsDRegister();
111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return static_cast<SRegister>(d_reg * 2 + 1);
112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  RegisterPair AsRegisterPair() const {
115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsRegisterPair());
116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    Register reg_low = AsRegisterPairLow();
1177a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    if (reg_low == R1) {
1187a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      return R1_R2;
1197a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    } else {
1207a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      return static_cast<RegisterPair>(reg_low / 2);
1217a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    }
122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Register AsRegisterPairLow() const {
125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsRegisterPair());
126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // Appropriate mapping of register ids allows to use AllocIdLow().
127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(AllocIdLow()).AsCoreRegister();
128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Register AsRegisterPairHigh() const {
131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsRegisterPair());
132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // Appropriate mapping of register ids allows to use AllocIdHigh().
133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(AllocIdHigh()).AsCoreRegister();
134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsCoreRegister() const {
137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= id_) && (id_ < kNumberOfCoreRegIds);
139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsSRegister() const {
142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test = id_ - kNumberOfCoreRegIds;
144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfSRegIds);
145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsDRegister() const {
148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds);
150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfDRegIds);
151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Returns true if this DRegister overlaps SRegisters.
154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsOverlappingDRegister() const {
155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds);
157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfOverlappingDRegIds);
158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsRegisterPair() const {
161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister());
162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int test =
163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds + kNumberOfDRegIds);
164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= test) && (test < kNumberOfPairRegIds);
165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  bool IsSameType(ArmManagedRegister test) const {
168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister() && test.IsValidManagedRegister());
169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return
170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      (IsCoreRegister() && test.IsCoreRegister()) ||
171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      (IsSRegister() && test.IsSRegister()) ||
172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      (IsDRegister() && test.IsDRegister()) ||
173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      (IsRegisterPair() && test.IsRegisterPair());
174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Returns true if the two managed-registers ('this' and 'other') overlap.
178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Either managed-register may be the NoRegister. If both are the NoRegister
179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // then false is returned.
1802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  bool Overlaps(const ArmManagedRegister& other) const;
181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void Print(std::ostream& os) const;
183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromCoreRegister(Register r) {
185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoRegister);
186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r);
187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromSRegister(SRegister r) {
190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoSRegister);
191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r + kNumberOfCoreRegIds);
192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromDRegister(DRegister r) {
195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoDRegister);
196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfSRegIds));
197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromRegisterPair(RegisterPair r) {
200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r, kNoRegisterPair);
201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromRegId(r + (kNumberOfCoreRegIds +
202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                          kNumberOfSRegIds + kNumberOfDRegIds));
203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Return a RegisterPair consisting of Register r_low and r_low + 1.
2062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromCoreRegisterPair(Register r_low) {
2077a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    if (r_low != R1) {  // not the dalvik special case
2087a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK_NE(r_low, kNoRegister);
2097a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK_EQ(0, (r_low % 2));
2107a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      const int r = r_low / 2;
2117a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK_LT(r, kNumberOfPairRegIds);
2127a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      return FromRegisterPair(static_cast<RegisterPair>(r));
2137a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    } else {
2147a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      return FromRegisterPair(R1_R2);
2157a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    }
216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Return a DRegister overlapping SRegister r_low and r_low + 1.
2192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromSRegisterPair(SRegister r_low) {
220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(r_low, kNoSRegister);
221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(0, (r_low % 2));
222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    const int r = r_low / 2;
223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_LT(r, kNumberOfOverlappingDRegIds);
224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return FromDRegister(static_cast<DRegister>(r));
225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private:
228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  bool IsValidManagedRegister() const {
229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return (0 <= id_) && (id_ < kNumberOfRegIds);
230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int RegId() const {
233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(!IsNoRegister());
234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return id_;
235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int AllocId() const {
238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(IsValidManagedRegister() &&
239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers           !IsOverlappingDRegister() && !IsRegisterPair());
240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    int r = id_;
241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if ((kNumberOfDAllocIds > 0) && IsDRegister()) {  // VFPv3-D32 only.
242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      r -= kNumberOfOverlappingDRegIds;
243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_LT(r, kNumberOfAllocIds);
245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return r;
246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int AllocIdLow() const;
249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  int AllocIdHigh() const;
250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  friend class ManagedRegister;
2522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
253a51a3dd5603daf3d368b7735067e1d9eb54c4c40Elliott Hughes  explicit ArmManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
2542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
2552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ArmManagedRegister FromRegId(int reg_id) {
2562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    ArmManagedRegister reg(reg_id);
257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(reg.IsValidManagedRegister());
258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return reg;
259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers};
261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersstd::ostream& operator<<(std::ostream& os, const ArmManagedRegister& reg);
2632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
2642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace arm
2652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
2662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline arm::ArmManagedRegister ManagedRegister::AsArm() const {
2672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  arm::ArmManagedRegister reg(id_);
2682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
2692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  return reg;
2702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}
271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}  // namespace art
273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
274166db04e259ca51838c311891598664deeed85adIan Rogers#endif  // ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_
275