1 /*
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 #include "managed_register_arm64.h"
18 #include "base/globals.h"
19 
20 namespace art {
21 namespace arm64 {
22 
23 // TODO: Define convention
24 //
25 // Do not use APCS callee saved regs for now. Use:
26 //  * [X0, X15]
27 //  * [W0, W15]
28 //  * [D0, D31]
29 //  * [S0, S31]
30 // static const int kNumberOfAvailableXRegisters = (X15 - X0) + 1;
31 // static const int kNumberOfAvailableWRegisters = (W15 - W0) + 1;
32 // static const int kNumberOfAvailableDRegisters = kNumberOfDRegisters;
33 // static const int kNumberOfAvailableSRegisters = kNumberOfSRegisters;
34 
35 // Returns true if this managed-register overlaps the other managed-register.
36 // GP Register Bank:
37 //       31____0 W[n]
38 // 63__________0 X[n]
39 //
40 // FP Register Bank:
41 //       31____0 S[n]
42 // 63__________0 D[n]
Overlaps(const Arm64ManagedRegister & other) const43 bool Arm64ManagedRegister::Overlaps(const Arm64ManagedRegister& other) const {
44   if (IsNoRegister() || other.IsNoRegister()) return false;
45   return (IsGPRegister() == other.IsGPRegister()) && (RegNo() == other.RegNo());
46 }
47 
RegNo() const48 int Arm64ManagedRegister::RegNo() const {
49   CHECK(!IsNoRegister());
50   int no;
51   if (IsXRegister()) {
52     no = static_cast<int>(AsXRegister());
53   } else if (IsWRegister()) {
54     no = static_cast<int>(AsWRegister());
55   } else if (IsDRegister()) {
56     no = static_cast<int>(AsDRegister());
57   } else if (IsSRegister()) {
58     no = static_cast<int>(AsSRegister());
59   } else {
60     no = kNoRegister;
61   }
62   return no;
63 }
64 
RegIdLow() const65 int Arm64ManagedRegister::RegIdLow() const {
66   CHECK(IsXRegister() || IsDRegister());
67   int low = RegNo();
68   if (IsXRegister()) {
69     low += kNumberOfXRegIds;
70   } else if (IsDRegister()) {
71     low += kNumberOfXRegIds + kNumberOfWRegIds + kNumberOfDRegIds;
72   }
73   return low;
74 }
75 
76 // FIXME: Find better naming.
RegIdHigh() const77 int Arm64ManagedRegister::RegIdHigh() const {
78   CHECK(IsWRegister() || IsSRegister());
79   int high = RegNo();
80   if (IsSRegister()) {
81     high += kNumberOfXRegIds + kNumberOfWRegIds;
82   }
83   return high;
84 }
85 
Print(std::ostream & os) const86 void Arm64ManagedRegister::Print(std::ostream& os) const {
87   if (!IsValidManagedRegister()) {
88     os << "No Register";
89   } else if (IsXRegister()) {
90     os << "XCore: " << static_cast<int>(AsXRegister());
91   } else if (IsWRegister()) {
92     os << "WCore: " << static_cast<int>(AsWRegister());
93   } else if (IsDRegister()) {
94     os << "DRegister: " << static_cast<int>(AsDRegister());
95   } else if (IsSRegister()) {
96     os << "SRegister: " << static_cast<int>(AsSRegister());
97   } else {
98     os << "??: " << RegId();
99   }
100 }
101 
operator <<(std::ostream & os,const Arm64ManagedRegister & reg)102 std::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg) {
103   reg.Print(os);
104   return os;
105 }
106 
107 }  // namespace arm64
108 }  // namespace art
109