blob: 7378a0a081e1758cca02963eed628d9ec3bb23e3 [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
Alexandre Rames087930f2016-08-02 13:45:28 +010020#include "arch/arm64/registers_arm64.h"
Serban Constantinescued8dd492014-02-11 14:15:10 +000021#include "base/logging.h"
David Srbecky4fda4eb2016-02-05 13:34:46 +000022#include "debug/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:
Vladimir Marko32248382016-05-19 10:37:24 +010059 constexpr XRegister AsXRegister() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +010060 CHECK(IsXRegister());
61 return static_cast<XRegister>(id_);
Serban Constantinescued8dd492014-02-11 14:15:10 +000062 }
63
Vladimir Marko32248382016-05-19 10:37:24 +010064 constexpr WRegister AsWRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000065 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
Vladimir Marko32248382016-05-19 10:37:24 +010069 constexpr DRegister AsDRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000070 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
Vladimir Marko32248382016-05-19 10:37:24 +010074 constexpr SRegister AsSRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000075 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
Vladimir Marko32248382016-05-19 10:37:24 +010080 constexpr 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
Vladimir Marko32248382016-05-19 10:37:24 +010086 constexpr 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
Vladimir Marko32248382016-05-19 10:37:24 +010091 constexpr SRegister AsOverlappingSRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000092 CHECK(IsValidManagedRegister());
93 return static_cast<SRegister>(AsDRegister());
94 }
95
Vladimir Marko32248382016-05-19 10:37:24 +010096 constexpr DRegister AsOverlappingDRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +000097 CHECK(IsValidManagedRegister());
98 return static_cast<DRegister>(AsSRegister());
99 }
100
Vladimir Marko32248382016-05-19 10:37:24 +0100101 constexpr 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
Vladimir Marko32248382016-05-19 10:37:24 +0100106 constexpr bool IsWRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000107 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
Vladimir Marko32248382016-05-19 10:37:24 +0100112 constexpr bool IsDRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000113 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
Vladimir Marko32248382016-05-19 10:37:24 +0100118 constexpr bool IsSRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000119 CHECK(IsValidManagedRegister());
Vladimir Marko80afd022015-05-19 18:08:00 +0100120 const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds + kNumberOfDRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000121 return (0 <= test) && (test < kNumberOfSRegIds);
122 }
123
Vladimir Marko32248382016-05-19 10:37:24 +0100124 constexpr bool IsGPRegister() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +0100125 return IsXRegister() || IsWRegister();
Serban Constantinescued8dd492014-02-11 14:15:10 +0000126 }
127
Vladimir Marko32248382016-05-19 10:37:24 +0100128 constexpr bool IsFPRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000129 return IsDRegister() || IsSRegister();
130 }
131
Vladimir Marko32248382016-05-19 10:37:24 +0100132 constexpr bool IsSameType(Arm64ManagedRegister test) const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000133 CHECK(IsValidManagedRegister() && test.IsValidManagedRegister());
134 return
Alexandre Rames37c92df2014-10-17 14:35:27 +0100135 (IsXRegister() && test.IsXRegister()) ||
Serban Constantinescued8dd492014-02-11 14:15:10 +0000136 (IsWRegister() && test.IsWRegister()) ||
137 (IsDRegister() && test.IsDRegister()) ||
138 (IsSRegister() && test.IsSRegister());
139 }
140
141 // Returns true if the two managed-registers ('this' and 'other') overlap.
142 // Either managed-register may be the NoRegister. If both are the NoRegister
143 // then false is returned.
144 bool Overlaps(const Arm64ManagedRegister& other) const;
145
146 void Print(std::ostream& os) const;
147
Vladimir Marko32248382016-05-19 10:37:24 +0100148 static constexpr Arm64ManagedRegister FromXRegister(XRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000149 CHECK_NE(r, kNoRegister);
150 return FromRegId(r);
151 }
152
Vladimir Marko32248382016-05-19 10:37:24 +0100153 static constexpr Arm64ManagedRegister FromWRegister(WRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000154 CHECK_NE(r, kNoWRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100155 return FromRegId(r + kNumberOfXRegIds);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000156 }
157
Vladimir Marko32248382016-05-19 10:37:24 +0100158 static constexpr Arm64ManagedRegister FromDRegister(DRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000159 CHECK_NE(r, kNoDRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100160 return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds));
Serban Constantinescued8dd492014-02-11 14:15:10 +0000161 }
162
Vladimir Marko32248382016-05-19 10:37:24 +0100163 static constexpr Arm64ManagedRegister FromSRegister(SRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000164 CHECK_NE(r, kNoSRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100165 return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds +
Serban Constantinescued8dd492014-02-11 14:15:10 +0000166 kNumberOfDRegIds));
167 }
168
169 // Returns the X register overlapping W register r.
Vladimir Marko32248382016-05-19 10:37:24 +0100170 static constexpr Arm64ManagedRegister FromWRegisterX(WRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000171 CHECK_NE(r, kNoWRegister);
172 return FromRegId(r);
173 }
174
175 // Return the D register overlapping S register r.
Vladimir Marko32248382016-05-19 10:37:24 +0100176 static constexpr Arm64ManagedRegister FromSRegisterD(SRegister r) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000177 CHECK_NE(r, kNoSRegister);
Alexandre Rames37c92df2014-10-17 14:35:27 +0100178 return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds));
Serban Constantinescued8dd492014-02-11 14:15:10 +0000179 }
180
181 private:
Vladimir Marko32248382016-05-19 10:37:24 +0100182 constexpr bool IsValidManagedRegister() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000183 return (0 <= id_) && (id_ < kNumberOfRegIds);
184 }
185
Vladimir Marko32248382016-05-19 10:37:24 +0100186 constexpr bool IsStackPointer() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +0100187 return IsXRegister() && (id_ == SP);
Serban Constantinescued8dd492014-02-11 14:15:10 +0000188 }
189
Vladimir Marko32248382016-05-19 10:37:24 +0100190 constexpr bool IsZeroRegister() const {
Alexandre Rames37c92df2014-10-17 14:35:27 +0100191 return IsXRegister() && (id_ == XZR);
Serban Constantinescu15523732014-04-02 13:18:05 +0100192 }
193
Vladimir Marko32248382016-05-19 10:37:24 +0100194 constexpr int RegId() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000195 CHECK(!IsNoRegister());
196 return id_;
197 }
198
199 int RegNo() const;
200 int RegIdLow() const;
201 int RegIdHigh() const;
202
203 friend class ManagedRegister;
204
Vladimir Marko32248382016-05-19 10:37:24 +0100205 explicit constexpr Arm64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
Serban Constantinescued8dd492014-02-11 14:15:10 +0000206
Vladimir Marko32248382016-05-19 10:37:24 +0100207 static constexpr Arm64ManagedRegister FromRegId(int reg_id) {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000208 Arm64ManagedRegister reg(reg_id);
209 CHECK(reg.IsValidManagedRegister());
210 return reg;
211 }
212};
213
214std::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg);
215
216} // namespace arm64
217
Vladimir Marko32248382016-05-19 10:37:24 +0100218constexpr inline arm64::Arm64ManagedRegister ManagedRegister::AsArm64() const {
Serban Constantinescued8dd492014-02-11 14:15:10 +0000219 arm64::Arm64ManagedRegister reg(id_);
220 CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
221 return reg;
222}
223
224} // namespace art
225
226#endif // ART_COMPILER_UTILS_ARM64_MANAGED_REGISTER_ARM64_H_