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 "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