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#ifndef ART_COMPILER_UTILS_MIPS64_MANAGED_REGISTER_MIPS64_H_
18#define ART_COMPILER_UTILS_MIPS64_MANAGED_REGISTER_MIPS64_H_
19
20#include "constants_mips64.h"
21#include "dwarf/register.h"
22#include "utils/managed_register.h"
23
24namespace art {
25namespace mips64 {
26
27const int kNumberOfGpuRegIds = kNumberOfGpuRegisters;
28const int kNumberOfGpuAllocIds = kNumberOfGpuRegisters;
29
30const int kNumberOfFpuRegIds = kNumberOfFpuRegisters;
31const int kNumberOfFpuAllocIds = kNumberOfFpuRegisters;
32
33const int kNumberOfRegIds = kNumberOfGpuRegIds + kNumberOfFpuRegIds;
34const int kNumberOfAllocIds = kNumberOfGpuAllocIds + kNumberOfFpuAllocIds;
35
36// An instance of class 'ManagedRegister' represents a single GPU register (enum
37// Register) or a double precision FP register (enum FpuRegister)
38// 'ManagedRegister::NoRegister()' provides an invalid register.
39// There is a one-to-one mapping between ManagedRegister and register id.
40class Mips64ManagedRegister : public ManagedRegister {
41 public:
42  GpuRegister AsGpuRegister() const {
43    CHECK(IsGpuRegister());
44    return static_cast<GpuRegister>(id_);
45  }
46
47  FpuRegister AsFpuRegister() const {
48    CHECK(IsFpuRegister());
49    return static_cast<FpuRegister>(id_ - kNumberOfGpuRegIds);
50  }
51
52  bool IsGpuRegister() const {
53    CHECK(IsValidManagedRegister());
54    return (0 <= id_) && (id_ < kNumberOfGpuRegIds);
55  }
56
57  bool IsFpuRegister() const {
58    CHECK(IsValidManagedRegister());
59    const int test = id_ - kNumberOfGpuRegIds;
60    return (0 <= test) && (test < kNumberOfFpuRegIds);
61  }
62
63  void Print(std::ostream& os) const;
64
65  // Returns true if the two managed-registers ('this' and 'other') overlap.
66  // Either managed-register may be the NoRegister. If both are the NoRegister
67  // then false is returned.
68  bool Overlaps(const Mips64ManagedRegister& other) const;
69
70  static Mips64ManagedRegister FromGpuRegister(GpuRegister r) {
71    CHECK_NE(r, kNoGpuRegister);
72    return FromRegId(r);
73  }
74
75  static Mips64ManagedRegister FromFpuRegister(FpuRegister r) {
76    CHECK_NE(r, kNoFpuRegister);
77    return FromRegId(r + kNumberOfGpuRegIds);
78  }
79
80 private:
81  bool IsValidManagedRegister() const {
82    return (0 <= id_) && (id_ < kNumberOfRegIds);
83  }
84
85  int RegId() const {
86    CHECK(!IsNoRegister());
87    return id_;
88  }
89
90  int AllocId() const {
91    CHECK(IsValidManagedRegister());
92    CHECK_LT(id_, kNumberOfAllocIds);
93    return id_;
94  }
95
96  int AllocIdLow() const;
97  int AllocIdHigh() const;
98
99  friend class ManagedRegister;
100
101  explicit Mips64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
102
103  static Mips64ManagedRegister FromRegId(int reg_id) {
104    Mips64ManagedRegister reg(reg_id);
105    CHECK(reg.IsValidManagedRegister());
106    return reg;
107  }
108};
109
110std::ostream& operator<<(std::ostream& os, const Mips64ManagedRegister& reg);
111
112}  // namespace mips64
113
114inline mips64::Mips64ManagedRegister ManagedRegister::AsMips64() const {
115  mips64::Mips64ManagedRegister reg(id_);
116  CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
117  return reg;
118}
119
120}  // namespace art
121
122#endif  // ART_COMPILER_UTILS_MIPS64_MANAGED_REGISTER_MIPS64_H_
123