xref: /aosp_15_r20/art/compiler/utils/riscv64/managed_register_riscv64.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2023 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_RISCV64_MANAGED_REGISTER_RISCV64_H_
18 #define ART_COMPILER_UTILS_RISCV64_MANAGED_REGISTER_RISCV64_H_
19 
20 #include <android-base/logging.h>
21 
22 #include "arch/riscv64/registers_riscv64.h"
23 #include "base/globals.h"
24 #include "base/macros.h"
25 #include "utils/managed_register.h"
26 
27 namespace art HIDDEN {
28 namespace riscv64 {
29 
30 const int kNumberOfXRegIds = kNumberOfXRegisters;
31 const int kNumberOfXAllocIds = kNumberOfXRegisters;
32 
33 const int kNumberOfFRegIds = kNumberOfFRegisters;
34 const int kNumberOfFAllocIds = kNumberOfFRegisters;
35 
36 const int kNumberOfRegIds = kNumberOfXRegIds + kNumberOfFRegIds;
37 const int kNumberOfAllocIds = kNumberOfXAllocIds + kNumberOfFAllocIds;
38 
39 // Register ids map:
40 //   [0..R[  core registers (enum XRegister)
41 //   [R..F[  floating-point registers (enum FRegister)
42 // where
43 //   R = kNumberOfXRegIds
44 //   F = R + kNumberOfFRegIds
45 
46 // An instance of class 'ManagedRegister' represents a single Riscv64 register.
47 // A register can be one of the following:
48 //  * core register (enum XRegister)
49 //  * floating-point register (enum FRegister)
50 //
51 // 'ManagedRegister::NoRegister()' provides an invalid register.
52 // There is a one-to-one mapping between ManagedRegister and register id.
53 class Riscv64ManagedRegister : public ManagedRegister {
54  public:
AsXRegister()55   constexpr XRegister AsXRegister() const {
56     CHECK(IsXRegister());
57     return static_cast<XRegister>(id_);
58   }
59 
AsFRegister()60   constexpr FRegister AsFRegister() const {
61     CHECK(IsFRegister());
62     return static_cast<FRegister>(id_ - kNumberOfXRegIds);
63   }
64 
IsXRegister()65   constexpr bool IsXRegister() const {
66     CHECK(IsValidManagedRegister());
67     return (0 <= id_) && (id_ < kNumberOfXRegIds);
68   }
69 
IsFRegister()70   constexpr bool IsFRegister() const {
71     CHECK(IsValidManagedRegister());
72     const int test = id_ - kNumberOfXRegIds;
73     return (0 <= test) && (test < kNumberOfFRegIds);
74   }
75 
76   void Print(std::ostream& os) const;
77 
78   // Returns true if the two managed-registers ('this' and 'other') overlap.
79   // Either managed-register may be the NoRegister. If both are the NoRegister
80   // then false is returned.
81   bool Overlaps(const Riscv64ManagedRegister& other) const;
82 
FromXRegister(XRegister r)83   static constexpr Riscv64ManagedRegister FromXRegister(XRegister r) {
84     CHECK_NE(r, kNoXRegister);
85     return FromRegId(r);
86   }
87 
FromFRegister(FRegister r)88   static constexpr Riscv64ManagedRegister FromFRegister(FRegister r) {
89     CHECK_NE(r, kNoFRegister);
90     return FromRegId(r + kNumberOfXRegIds);
91   }
92 
93  private:
IsValidManagedRegister()94   constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); }
95 
RegId()96   constexpr int RegId() const {
97     CHECK(!IsNoRegister());
98     return id_;
99   }
100 
AllocId()101   int AllocId() const {
102     CHECK(IsValidManagedRegister());
103     CHECK_LT(id_, kNumberOfAllocIds);
104     return id_;
105   }
106 
107   int AllocIdLow() const;
108   int AllocIdHigh() const;
109 
110   friend class ManagedRegister;
111 
Riscv64ManagedRegister(int reg_id)112   explicit constexpr Riscv64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
113 
FromRegId(int reg_id)114   static constexpr Riscv64ManagedRegister FromRegId(int reg_id) {
115     Riscv64ManagedRegister reg(reg_id);
116     CHECK(reg.IsValidManagedRegister());
117     return reg;
118   }
119 };
120 
121 std::ostream& operator<<(std::ostream& os, const Riscv64ManagedRegister& reg);
122 
123 }  // namespace riscv64
124 
AsRiscv64()125 constexpr inline riscv64::Riscv64ManagedRegister ManagedRegister::AsRiscv64() const {
126   riscv64::Riscv64ManagedRegister reg(id_);
127   CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
128   return reg;
129 }
130 
131 }  // namespace art
132 
133 #endif  // ART_COMPILER_UTILS_RISCV64_MANAGED_REGISTER_RISCV64_H_
134