Home | History | Annotate | Download | only in mips
      1 /*
      2  * Copyright (C) 2011 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_MIPS_MANAGED_REGISTER_MIPS_H_
     18 #define ART_COMPILER_UTILS_MIPS_MANAGED_REGISTER_MIPS_H_
     19 
     20 #include "constants_mips.h"
     21 #include "debug/dwarf/register.h"
     22 #include "utils/managed_register.h"
     23 
     24 namespace art {
     25 namespace mips {
     26 
     27 // Values for register pairs.
     28 enum RegisterPair {
     29   V0_V1 = 0,
     30   A0_A1 = 1,
     31   A2_A3 = 2,
     32   T0_T1 = 3,
     33   T2_T3 = 4,
     34   T4_T5 = 5,
     35   T6_T7 = 6,
     36   S0_S1 = 7,
     37   S2_S3 = 8,
     38   S4_S5 = 9,
     39   S6_S7 = 10,
     40   A1_A2 = 11,  // Dalvik style passing
     41   kNumberOfRegisterPairs = 12,
     42   kNoRegisterPair = -1,
     43 };
     44 
     45 std::ostream& operator<<(std::ostream& os, const RegisterPair& reg);
     46 
     47 const int kNumberOfCoreRegIds = kNumberOfCoreRegisters;
     48 const int kNumberOfCoreAllocIds = kNumberOfCoreRegisters;
     49 
     50 const int kNumberOfFRegIds = kNumberOfFRegisters;
     51 const int kNumberOfFAllocIds = kNumberOfFRegisters;
     52 
     53 const int kNumberOfDRegIds = kNumberOfDRegisters;
     54 const int kNumberOfOverlappingDRegIds = kNumberOfOverlappingDRegisters;
     55 const int kNumberOfDAllocIds = kNumberOfDRegisters;
     56 
     57 const int kNumberOfPairRegIds = kNumberOfRegisterPairs;
     58 
     59 const int kNumberOfRegIds = kNumberOfCoreRegIds + kNumberOfFRegIds +
     60     kNumberOfDRegIds + kNumberOfPairRegIds;
     61 const int kNumberOfAllocIds =
     62     kNumberOfCoreAllocIds + kNumberOfFAllocIds + kNumberOfDAllocIds;
     63 
     64 // Register ids map:
     65 //   [0..R[  core registers (enum Register)
     66 //   [R..F[  single precision FP registers (enum FRegister)
     67 //   [F..D[  double precision FP registers (enum DRegister)
     68 //   [D..P[  core register pairs (enum RegisterPair)
     69 // where
     70 //   R = kNumberOfCoreRegIds
     71 //   F = R + kNumberOfFRegIds
     72 //   D = F + kNumberOfDRegIds
     73 //   P = D + kNumberOfRegisterPairs
     74 
     75 // Allocation ids map:
     76 //   [0..R[  core registers (enum Register)
     77 //   [R..F[  single precision FP registers (enum FRegister)
     78 // where
     79 //   R = kNumberOfCoreRegIds
     80 //   F = R + kNumberOfFRegIds
     81 
     82 
     83 // An instance of class 'ManagedRegister' represents a single core register (enum
     84 // Register), a single precision FP register (enum FRegister), a double precision
     85 // FP register (enum DRegister), or a pair of core registers (enum RegisterPair).
     86 // 'ManagedRegister::NoRegister()' provides an invalid register.
     87 // There is a one-to-one mapping between ManagedRegister and register id.
     88 class MipsManagedRegister : public ManagedRegister {
     89  public:
     90   constexpr Register AsCoreRegister() const {
     91     CHECK(IsCoreRegister());
     92     return static_cast<Register>(id_);
     93   }
     94 
     95   constexpr FRegister AsFRegister() const {
     96     CHECK(IsFRegister());
     97     return static_cast<FRegister>(id_ - kNumberOfCoreRegIds);
     98   }
     99 
    100   constexpr DRegister AsDRegister() const {
    101     CHECK(IsDRegister());
    102     return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfFRegIds);
    103   }
    104 
    105   constexpr FRegister AsOverlappingDRegisterLow() const {
    106     CHECK(IsOverlappingDRegister());
    107     DRegister d_reg = AsDRegister();
    108     return static_cast<FRegister>(d_reg * 2);
    109   }
    110 
    111   constexpr FRegister AsOverlappingDRegisterHigh() const {
    112     CHECK(IsOverlappingDRegister());
    113     DRegister d_reg = AsDRegister();
    114     return static_cast<FRegister>(d_reg * 2 + 1);
    115   }
    116 
    117   constexpr Register AsRegisterPairLow() const {
    118     CHECK(IsRegisterPair());
    119     // Appropriate mapping of register ids allows to use AllocIdLow().
    120     return FromRegId(AllocIdLow()).AsCoreRegister();
    121   }
    122 
    123   constexpr Register AsRegisterPairHigh() const {
    124     CHECK(IsRegisterPair());
    125     // Appropriate mapping of register ids allows to use AllocIdHigh().
    126     return FromRegId(AllocIdHigh()).AsCoreRegister();
    127   }
    128 
    129   constexpr bool IsCoreRegister() const {
    130     CHECK(IsValidManagedRegister());
    131     return (0 <= id_) && (id_ < kNumberOfCoreRegIds);
    132   }
    133 
    134   constexpr bool IsFRegister() const {
    135     CHECK(IsValidManagedRegister());
    136     const int test = id_ - kNumberOfCoreRegIds;
    137     return (0 <= test) && (test < kNumberOfFRegIds);
    138   }
    139 
    140   constexpr bool IsDRegister() const {
    141     CHECK(IsValidManagedRegister());
    142     const int test = id_ - (kNumberOfCoreRegIds + kNumberOfFRegIds);
    143     return (0 <= test) && (test < kNumberOfDRegIds);
    144   }
    145 
    146   // Returns true if this DRegister overlaps FRegisters.
    147   constexpr bool IsOverlappingDRegister() const {
    148     CHECK(IsValidManagedRegister());
    149     const int test = id_ - (kNumberOfCoreRegIds + kNumberOfFRegIds);
    150     return (0 <= test) && (test < kNumberOfOverlappingDRegIds);
    151   }
    152 
    153   constexpr bool IsRegisterPair() const {
    154     CHECK(IsValidManagedRegister());
    155     const int test =
    156         id_ - (kNumberOfCoreRegIds + kNumberOfFRegIds + kNumberOfDRegIds);
    157     return (0 <= test) && (test < kNumberOfPairRegIds);
    158   }
    159 
    160   void Print(std::ostream& os) const;
    161 
    162   // Returns true if the two managed-registers ('this' and 'other') overlap.
    163   // Either managed-register may be the NoRegister. If both are the NoRegister
    164   // then false is returned.
    165   bool Overlaps(const MipsManagedRegister& other) const;
    166 
    167   static constexpr MipsManagedRegister FromCoreRegister(Register r) {
    168     CHECK_NE(r, kNoRegister);
    169     return FromRegId(r);
    170   }
    171 
    172   static constexpr MipsManagedRegister FromFRegister(FRegister r) {
    173     CHECK_NE(r, kNoFRegister);
    174     return FromRegId(r + kNumberOfCoreRegIds);
    175   }
    176 
    177   static constexpr MipsManagedRegister FromDRegister(DRegister r) {
    178     CHECK_NE(r, kNoDRegister);
    179     return FromRegId(r + kNumberOfCoreRegIds + kNumberOfFRegIds);
    180   }
    181 
    182   static constexpr MipsManagedRegister FromRegisterPair(RegisterPair r) {
    183     CHECK_NE(r, kNoRegisterPair);
    184     return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfFRegIds + kNumberOfDRegIds));
    185   }
    186 
    187  private:
    188   constexpr bool IsValidManagedRegister() const {
    189     return (0 <= id_) && (id_ < kNumberOfRegIds);
    190   }
    191 
    192   constexpr int RegId() const {
    193     CHECK(!IsNoRegister());
    194     return id_;
    195   }
    196 
    197   int AllocId() const {
    198     CHECK(IsValidManagedRegister() && !IsOverlappingDRegister() && !IsRegisterPair());
    199     CHECK_LT(id_, kNumberOfAllocIds);
    200     return id_;
    201   }
    202 
    203   int AllocIdLow() const;
    204   int AllocIdHigh() const;
    205 
    206   friend class ManagedRegister;
    207 
    208   explicit constexpr MipsManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
    209 
    210   static constexpr MipsManagedRegister FromRegId(int reg_id) {
    211     MipsManagedRegister reg(reg_id);
    212     CHECK(reg.IsValidManagedRegister());
    213     return reg;
    214   }
    215 };
    216 
    217 std::ostream& operator<<(std::ostream& os, const MipsManagedRegister& reg);
    218 
    219 }  // namespace mips
    220 
    221 constexpr inline mips::MipsManagedRegister ManagedRegister::AsMips() const {
    222   mips::MipsManagedRegister reg(id_);
    223   CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
    224   return reg;
    225 }
    226 
    227 }  // namespace art
    228 
    229 #endif  // ART_COMPILER_UTILS_MIPS_MANAGED_REGISTER_MIPS_H_
    230