blob: 62c1d4dbeecea931f89573e9cebf1e532f40dd53 [file] [log] [blame]
Serban Constantinescued8dd492014-02-11 14:15:10 +00001/*
2 * Copyright (C) 2014 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#ifndef ART_COMPILER_UTILS_ARM64_MANAGED_REGISTER_ARM64_H_
18#define ART_COMPILER_UTILS_ARM64_MANAGED_REGISTER_ARM64_H_
19
20#include "base/logging.h"
21#include "constants_arm64.h"
David Srbeckydd973932015-04-07 20:29:48 +010022#include "dwarf/register.h"
Serban Constantinescued8dd492014-02-11 14:15:10 +000023#include "utils/managed_register.h"
24
25namespace art {
26namespace arm64 {
27
Alexandre Rames37c92df2014-10-17 14:35:27 +010028const int kNumberOfXRegIds = kNumberOfXRegisters;
Serban Constantinescued8dd492014-02-11 14:15:10 +000029const int kNumberOfWRegIds = kNumberOfWRegisters;
30const int kNumberOfDRegIds = kNumberOfDRegisters;
31const int kNumberOfSRegIds = kNumberOfSRegisters;
32
Alexandre Rames37c92df2014-10-17 14:35:27 +010033const int kNumberOfRegIds = kNumberOfXRegIds + kNumberOfWRegIds +
Serban Constantinescued8dd492014-02-11 14:15:10 +000034 kNumberOfDRegIds + kNumberOfSRegIds;
35
36// Register ids map:
Alexandre Rames37c92df2014-10-17 14:35:27 +010037// [0..X[ core registers 64bit (enum XRegister)
Serban Constantinescued8dd492014-02-11 14:15:10 +000038// [X..W[ core registers 32bit (enum WRegister)
39// [W..D[ double precision VFP registers (enum DRegister)
40// [D..S[ single precision VFP registers (enum SRegister)
41//
42// where:
Alexandre Rames37c92df2014-10-17 14:35:27 +010043// X = kNumberOfXRegIds
Serban Constantinescued8dd492014-02-11 14:15:10 +000044// W = X + kNumberOfWRegIds
45// D = W + kNumberOfDRegIds
46// S = D + kNumberOfSRegIds
47//
48// An instance of class 'ManagedRegister' represents a single Arm64
49// register. A register can be one of the following:
Alexandre Rames37c92df2014-10-17 14:35:27 +010050// * core register 64bit context (enum XRegister)
Serban Constantinescued8dd492014-02-11 14:15:10 +000051// * core register 32bit context (enum WRegister)
52// * VFP double precision register (enum DRegister)
53// * VFP single precision register (enum SRegister)
54//
55// There is a one to one mapping between ManagedRegister and register id.
56
57class Arm64ManagedRegister : public ManagedRegister {
58 public:
Alexandre Rames37c92df2014-10-17 14:35:27 +010059 XRegister AsXRegister() const {
60 CHECK(IsXRegister());
61 return static_cast<XRegister>(id_);
Serban Constantinescued8dd492014-02-11 14:15:10 +000062 }
63
64 WRegister AsWRegister() const {
65 CHECK(IsWRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +010066 return static_cast<WRegister>(id_ - kNumberOfXRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +000067 }
68
69 DRegister AsDRegister() const {
70 CHECK(IsDRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +010071 return static_cast<DRegister>(id_ - kNumberOfXRegIds - kNumberOfWRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +000072 }
73
74 SRegister AsSRegister() const {
75 CHECK(IsSRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +010076 return static_cast<SRegister>(id_ - kNumberOfXRegIds - kNumberOfWRegIds -
Serban Constantinescued8dd492014-02-11 14:15:10 +000077 kNumberOfDRegIds);
78 }
79
Alexandre Rames37c92df2014-10-17 14:35:27 +010080 WRegister AsOverlappingWRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000081 CHECK(IsValidManagedRegister());
Alexandre Ramesa304f972014-10-17 14:35:27 +010082 if (IsZeroRegister()) return WZR;
Alexandre Rames37c92df2014-10-17 14:35:27 +010083 return static_cast<WRegister>(AsXRegister());
Serban Constantinescued8dd492014-02-11 14:15:10 +000084 }
85
Alexandre Rames37c92df2014-10-17 14:35:27 +010086 XRegister AsOverlappingXRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000087 CHECK(IsValidManagedRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +010088 return static_cast<XRegister>(AsWRegister());
Serban Constantinescued8dd492014-02-11 14:15:10 +000089 }
90
Alexandre Rames37c92df2014-10-17 14:35:27 +010091 SRegister AsOverlappingSRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000092 CHECK(IsValidManagedRegister());
93 return static_cast<SRegister>(AsDRegister());
94 }
95
Alexandre Rames37c92df2014-10-17 14:35:27 +010096 DRegister AsOverlappingDRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000097 CHECK(IsValidManagedRegister());
98 return static_cast<DRegister>(AsSRegister());
99 }
100
Alexandre Rames37c92df2014-10-17 14:35:27 +0100101 bool IsXRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000102 CHECK(IsValidManagedRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +0100103 return (0 <= id_) && (id_ < kNumberOfXRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000104 }
105
106 bool IsWRegister() const {
107 CHECK(IsValidManagedRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +0100108 const int test = id_ - kNumberOfXRegIds;
Serban Constantinescued8dd492014-02-11 14:15:10 +0000109 return (0 <= test) && (test < kNumberOfWRegIds);
110 }
111
112 bool IsDRegister() const {
113 CHECK(IsValidManagedRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +0100114 const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000115 return (0 <= test) && (test < kNumberOfDRegIds);
116 }
117
118 bool IsSRegister() const {
119 CHECK(IsValidManagedRegister());
Alexandre Rames37c92df2014-10-17 14:35:27 +0100120 const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds +
Serban Constantinescued8dd492014-02-11 14:15:10 +0000121 kNumberOfDRegIds);
122 return (0 <= test) && (test < kNumberOfSRegIds);
123 }
124
125 bool IsGPRegister() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +0100126 return IsXRegister() || IsWRegister();
Serban Constantinescued8dd492014-02-11 14:15:10 +0000127 }
128
129 bool IsFPRegister() const {
130 return IsDRegister() || IsSRegister();
131 }
132
133 bool IsSameType(Arm64ManagedRegister test) const {
134 CHECK(IsValidManagedRegister() && test.IsValidManagedRegister());
135 return
Alexandre Rames37c92df2014-10-17 14:35:27 +0100136 (IsXRegister() && test.IsXRegister()) ||
Serban Constantinescued8dd492014-02-11 14:15:10 +0000137 (IsWRegister() && test.IsWRegister()) ||
138 (IsDRegister() && test.IsDRegister()) ||
139 (IsSRegister() && test.IsSRegister());
140 }
141
142 // Returns true if the two managed-registers ('this' and 'other') overlap.
143 // Either managed-register may be the NoRegister. If both are the NoRegister
144 // then false is returned.
145 bool Overlaps(const Arm64ManagedRegister& other) const;
146
147 void Print(std::ostream& os) const;
148
Alexandre Rames37c92df2014-10-17 14:35:27 +0100149 static Arm64ManagedRegister FromXRegister(XRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000150 CHECK_NE(r, kNoRegister);
151 return FromRegId(r);
152 }
153
154 static Arm64ManagedRegister FromWRegister(WRegister r) {
155 CHECK_NE(r, kNoWRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100156 return FromRegId(r + kNumberOfXRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000157 }
158
159 static Arm64ManagedRegister FromDRegister(DRegister r) {
160 CHECK_NE(r, kNoDRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100161 return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds));
Serban Constantinescued8dd492014-02-11 14:15:10 +0000162 }
163
164 static Arm64ManagedRegister FromSRegister(SRegister r) {
165 CHECK_NE(r, kNoSRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100166 return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds +
Serban Constantinescued8dd492014-02-11 14:15:10 +0000167 kNumberOfDRegIds));
168 }
169
170 // Returns the X register overlapping W register r.
Alexandre Rames37c92df2014-10-17 14:35:27 +0100171 static Arm64ManagedRegister FromWRegisterX(WRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000172 CHECK_NE(r, kNoWRegister);
173 return FromRegId(r);
174 }
175
176 // Return the D register overlapping S register r.
177 static Arm64ManagedRegister FromSRegisterD(SRegister r) {
178 CHECK_NE(r, kNoSRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100179 return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds));
Serban Constantinescued8dd492014-02-11 14:15:10 +0000180 }
181
182 private:
183 bool IsValidManagedRegister() const {
184 return (0 <= id_) && (id_ < kNumberOfRegIds);
185 }
186
187 bool IsStackPointer() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +0100188 return IsXRegister() && (id_ == SP);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000189 }
190
Serban Constantinescu15523732014-04-02 13:18:05 +0100191 bool IsZeroRegister() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +0100192 return IsXRegister() && (id_ == XZR);
Serban Constantinescu15523732014-04-02 13:18:05 +0100193 }
194
Serban Constantinescued8dd492014-02-11 14:15:10 +0000195 int RegId() const {
196 CHECK(!IsNoRegister());
197 return id_;
198 }
199
200 int RegNo() const;
201 int RegIdLow() const;
202 int RegIdHigh() const;
203
204 friend class ManagedRegister;
205
206 explicit Arm64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
207
208 static Arm64ManagedRegister FromRegId(int reg_id) {
209 Arm64ManagedRegister reg(reg_id);
210 CHECK(reg.IsValidManagedRegister());
211 return reg;
212 }
213};
214
215std::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg);
216
217} // namespace arm64
218
219inline arm64::Arm64ManagedRegister ManagedRegister::AsArm64() const {
220 arm64::Arm64ManagedRegister reg(id_);
221 CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
222 return reg;
223}
224
225} // namespace art
226
227#endif // ART_COMPILER_UTILS_ARM64_MANAGED_REGISTER_ARM64_H_