1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_COMPILER_UTILS_RISCV64_MANAGED_REGISTER_RISCV64_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_UTILS_RISCV64_MANAGED_REGISTER_RISCV64_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "arch/riscv64/registers_riscv64.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/globals.h" 24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 25*795d594fSAndroid Build Coastguard Worker #include "utils/managed_register.h" 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 28*795d594fSAndroid Build Coastguard Worker namespace riscv64 { 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker const int kNumberOfXRegIds = kNumberOfXRegisters; 31*795d594fSAndroid Build Coastguard Worker const int kNumberOfXAllocIds = kNumberOfXRegisters; 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker const int kNumberOfFRegIds = kNumberOfFRegisters; 34*795d594fSAndroid Build Coastguard Worker const int kNumberOfFAllocIds = kNumberOfFRegisters; 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker const int kNumberOfRegIds = kNumberOfXRegIds + kNumberOfFRegIds; 37*795d594fSAndroid Build Coastguard Worker const int kNumberOfAllocIds = kNumberOfXAllocIds + kNumberOfFAllocIds; 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker // Register ids map: 40*795d594fSAndroid Build Coastguard Worker // [0..R[ core registers (enum XRegister) 41*795d594fSAndroid Build Coastguard Worker // [R..F[ floating-point registers (enum FRegister) 42*795d594fSAndroid Build Coastguard Worker // where 43*795d594fSAndroid Build Coastguard Worker // R = kNumberOfXRegIds 44*795d594fSAndroid Build Coastguard Worker // F = R + kNumberOfFRegIds 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker // An instance of class 'ManagedRegister' represents a single Riscv64 register. 47*795d594fSAndroid Build Coastguard Worker // A register can be one of the following: 48*795d594fSAndroid Build Coastguard Worker // * core register (enum XRegister) 49*795d594fSAndroid Build Coastguard Worker // * floating-point register (enum FRegister) 50*795d594fSAndroid Build Coastguard Worker // 51*795d594fSAndroid Build Coastguard Worker // 'ManagedRegister::NoRegister()' provides an invalid register. 52*795d594fSAndroid Build Coastguard Worker // There is a one-to-one mapping between ManagedRegister and register id. 53*795d594fSAndroid Build Coastguard Worker class Riscv64ManagedRegister : public ManagedRegister { 54*795d594fSAndroid Build Coastguard Worker public: AsXRegister()55*795d594fSAndroid Build Coastguard Worker constexpr XRegister AsXRegister() const { 56*795d594fSAndroid Build Coastguard Worker CHECK(IsXRegister()); 57*795d594fSAndroid Build Coastguard Worker return static_cast<XRegister>(id_); 58*795d594fSAndroid Build Coastguard Worker } 59*795d594fSAndroid Build Coastguard Worker AsFRegister()60*795d594fSAndroid Build Coastguard Worker constexpr FRegister AsFRegister() const { 61*795d594fSAndroid Build Coastguard Worker CHECK(IsFRegister()); 62*795d594fSAndroid Build Coastguard Worker return static_cast<FRegister>(id_ - kNumberOfXRegIds); 63*795d594fSAndroid Build Coastguard Worker } 64*795d594fSAndroid Build Coastguard Worker IsXRegister()65*795d594fSAndroid Build Coastguard Worker constexpr bool IsXRegister() const { 66*795d594fSAndroid Build Coastguard Worker CHECK(IsValidManagedRegister()); 67*795d594fSAndroid Build Coastguard Worker return (0 <= id_) && (id_ < kNumberOfXRegIds); 68*795d594fSAndroid Build Coastguard Worker } 69*795d594fSAndroid Build Coastguard Worker IsFRegister()70*795d594fSAndroid Build Coastguard Worker constexpr bool IsFRegister() const { 71*795d594fSAndroid Build Coastguard Worker CHECK(IsValidManagedRegister()); 72*795d594fSAndroid Build Coastguard Worker const int test = id_ - kNumberOfXRegIds; 73*795d594fSAndroid Build Coastguard Worker return (0 <= test) && (test < kNumberOfFRegIds); 74*795d594fSAndroid Build Coastguard Worker } 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker void Print(std::ostream& os) const; 77*795d594fSAndroid Build Coastguard Worker 78*795d594fSAndroid Build Coastguard Worker // Returns true if the two managed-registers ('this' and 'other') overlap. 79*795d594fSAndroid Build Coastguard Worker // Either managed-register may be the NoRegister. If both are the NoRegister 80*795d594fSAndroid Build Coastguard Worker // then false is returned. 81*795d594fSAndroid Build Coastguard Worker bool Overlaps(const Riscv64ManagedRegister& other) const; 82*795d594fSAndroid Build Coastguard Worker FromXRegister(XRegister r)83*795d594fSAndroid Build Coastguard Worker static constexpr Riscv64ManagedRegister FromXRegister(XRegister r) { 84*795d594fSAndroid Build Coastguard Worker CHECK_NE(r, kNoXRegister); 85*795d594fSAndroid Build Coastguard Worker return FromRegId(r); 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker FromFRegister(FRegister r)88*795d594fSAndroid Build Coastguard Worker static constexpr Riscv64ManagedRegister FromFRegister(FRegister r) { 89*795d594fSAndroid Build Coastguard Worker CHECK_NE(r, kNoFRegister); 90*795d594fSAndroid Build Coastguard Worker return FromRegId(r + kNumberOfXRegIds); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker private: IsValidManagedRegister()94*795d594fSAndroid Build Coastguard Worker constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } 95*795d594fSAndroid Build Coastguard Worker RegId()96*795d594fSAndroid Build Coastguard Worker constexpr int RegId() const { 97*795d594fSAndroid Build Coastguard Worker CHECK(!IsNoRegister()); 98*795d594fSAndroid Build Coastguard Worker return id_; 99*795d594fSAndroid Build Coastguard Worker } 100*795d594fSAndroid Build Coastguard Worker AllocId()101*795d594fSAndroid Build Coastguard Worker int AllocId() const { 102*795d594fSAndroid Build Coastguard Worker CHECK(IsValidManagedRegister()); 103*795d594fSAndroid Build Coastguard Worker CHECK_LT(id_, kNumberOfAllocIds); 104*795d594fSAndroid Build Coastguard Worker return id_; 105*795d594fSAndroid Build Coastguard Worker } 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker int AllocIdLow() const; 108*795d594fSAndroid Build Coastguard Worker int AllocIdHigh() const; 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker friend class ManagedRegister; 111*795d594fSAndroid Build Coastguard Worker Riscv64ManagedRegister(int reg_id)112*795d594fSAndroid Build Coastguard Worker explicit constexpr Riscv64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} 113*795d594fSAndroid Build Coastguard Worker FromRegId(int reg_id)114*795d594fSAndroid Build Coastguard Worker static constexpr Riscv64ManagedRegister FromRegId(int reg_id) { 115*795d594fSAndroid Build Coastguard Worker Riscv64ManagedRegister reg(reg_id); 116*795d594fSAndroid Build Coastguard Worker CHECK(reg.IsValidManagedRegister()); 117*795d594fSAndroid Build Coastguard Worker return reg; 118*795d594fSAndroid Build Coastguard Worker } 119*795d594fSAndroid Build Coastguard Worker }; 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const Riscv64ManagedRegister& reg); 122*795d594fSAndroid Build Coastguard Worker 123*795d594fSAndroid Build Coastguard Worker } // namespace riscv64 124*795d594fSAndroid Build Coastguard Worker AsRiscv64()125*795d594fSAndroid Build Coastguard Workerconstexpr inline riscv64::Riscv64ManagedRegister ManagedRegister::AsRiscv64() const { 126*795d594fSAndroid Build Coastguard Worker riscv64::Riscv64ManagedRegister reg(id_); 127*795d594fSAndroid Build Coastguard Worker CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); 128*795d594fSAndroid Build Coastguard Worker return reg; 129*795d594fSAndroid Build Coastguard Worker } 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker } // namespace art 132*795d594fSAndroid Build Coastguard Worker 133*795d594fSAndroid Build Coastguard Worker #endif // ART_COMPILER_UTILS_RISCV64_MANAGED_REGISTER_RISCV64_H_ 134