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 kNumberOfAvailableCoreRegisters = (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] 43 bool Arm64ManagedRegister::Overlaps(const Arm64ManagedRegister& other) const { 44 if (IsNoRegister() || other.IsNoRegister()) return false; 45 if ((IsGPRegister() && other.IsGPRegister()) || 46 (IsFPRegister() && other.IsFPRegister())) { 47 return (RegNo() == other.RegNo()); 48 } 49 return false; 50 } 51 52 int Arm64ManagedRegister::RegNo() const { 53 CHECK(!IsNoRegister()); 54 int no; 55 if (IsCoreRegister()) { 56 if (IsZeroRegister()) { 57 no = static_cast<int>(X31); 58 } else { 59 no = static_cast<int>(AsCoreRegister()); 60 } 61 } else if (IsWRegister()) { 62 no = static_cast<int>(AsWRegister()); 63 } else if (IsDRegister()) { 64 no = static_cast<int>(AsDRegister()); 65 } else if (IsSRegister()) { 66 no = static_cast<int>(AsSRegister()); 67 } else { 68 no = kNoRegister; 69 } 70 return no; 71 } 72 73 int Arm64ManagedRegister::RegIdLow() const { 74 CHECK(IsCoreRegister() || IsDRegister()); 75 int low = RegNo(); 76 if (IsCoreRegister()) { 77 low += kNumberOfCoreRegIds; 78 } else if (IsDRegister()) { 79 low += kNumberOfCoreRegIds + kNumberOfWRegIds + kNumberOfDRegIds; 80 } 81 return low; 82 } 83 84 // FIXME: Find better naming. 85 int Arm64ManagedRegister::RegIdHigh() const { 86 CHECK(IsWRegister() || IsSRegister()); 87 int high = RegNo(); 88 if (IsSRegister()) { 89 high += kNumberOfCoreRegIds + kNumberOfWRegIds; 90 } 91 return high; 92 } 93 94 void Arm64ManagedRegister::Print(std::ostream& os) const { 95 if (!IsValidManagedRegister()) { 96 os << "No Register"; 97 } else if (IsCoreRegister()) { 98 os << "XCore: " << static_cast<int>(AsCoreRegister()); 99 } else if (IsWRegister()) { 100 os << "WCore: " << static_cast<int>(AsWRegister()); 101 } else if (IsDRegister()) { 102 os << "DRegister: " << static_cast<int>(AsDRegister()); 103 } else if (IsSRegister()) { 104 os << "SRegister: " << static_cast<int>(AsSRegister()); 105 } else { 106 os << "??: " << RegId(); 107 } 108 } 109 110 std::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg) { 111 reg.Print(os); 112 return os; 113 } 114 115 } // namespace arm64 116 } // namespace art 117