Home | History | Annotate | Download | only in x86_64
      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_X86_64_MANAGED_REGISTER_X86_64_H_
     18 #define ART_COMPILER_UTILS_X86_64_MANAGED_REGISTER_X86_64_H_
     19 
     20 #include "constants_x86_64.h"
     21 #include "utils/managed_register.h"
     22 
     23 namespace art {
     24 namespace x86_64 {
     25 
     26 // Values for register pairs.
     27 // The registers in kReservedCpuRegistersArray in x86.cc are not used in pairs.
     28 // The table kRegisterPairs in x86.cc must be kept in sync with this enum.
     29 enum RegisterPair {
     30   RAX_RDX = 0,
     31   RAX_RCX = 1,
     32   RAX_RBX = 2,
     33   RAX_RDI = 3,
     34   RDX_RCX = 4,
     35   RDX_RBX = 5,
     36   RDX_RDI = 6,
     37   RCX_RBX = 7,
     38   RCX_RDI = 8,
     39   RBX_RDI = 9,
     40   kNumberOfRegisterPairs = 10,
     41   kNoRegisterPair = -1,
     42 };
     43 
     44 std::ostream& operator<<(std::ostream& os, const RegisterPair& reg);
     45 
     46 const int kNumberOfCpuRegIds = kNumberOfCpuRegisters;
     47 const int kNumberOfCpuAllocIds = kNumberOfCpuRegisters;
     48 
     49 const int kNumberOfXmmRegIds = kNumberOfFloatRegisters;
     50 const int kNumberOfXmmAllocIds = kNumberOfFloatRegisters;
     51 
     52 const int kNumberOfX87RegIds = kNumberOfX87Registers;
     53 const int kNumberOfX87AllocIds = kNumberOfX87Registers;
     54 
     55 const int kNumberOfPairRegIds = kNumberOfRegisterPairs;
     56 
     57 const int kNumberOfRegIds = kNumberOfCpuRegIds + kNumberOfXmmRegIds +
     58     kNumberOfX87RegIds + kNumberOfPairRegIds;
     59 const int kNumberOfAllocIds = kNumberOfCpuAllocIds + kNumberOfXmmAllocIds +
     60     kNumberOfX87RegIds;
     61 
     62 // Register ids map:
     63 //   [0..R[  cpu registers (enum Register)
     64 //   [R..X[  xmm registers (enum XmmRegister)
     65 //   [X..S[  x87 registers (enum X87Register)
     66 //   [S..P[  register pairs (enum RegisterPair)
     67 // where
     68 //   R = kNumberOfCpuRegIds
     69 //   X = R + kNumberOfXmmRegIds
     70 //   S = X + kNumberOfX87RegIds
     71 //   P = X + kNumberOfRegisterPairs
     72 
     73 // Allocation ids map:
     74 //   [0..R[  cpu registers (enum Register)
     75 //   [R..X[  xmm registers (enum XmmRegister)
     76 //   [X..S[  x87 registers (enum X87Register)
     77 // where
     78 //   R = kNumberOfCpuRegIds
     79 //   X = R + kNumberOfXmmRegIds
     80 //   S = X + kNumberOfX87RegIds
     81 
     82 
     83 // An instance of class 'ManagedRegister' represents a single cpu register (enum
     84 // Register), an xmm register (enum XmmRegister), or a pair of cpu registers
     85 // (enum RegisterPair).
     86 // 'ManagedRegister::NoRegister()' provides an invalid register.
     87 // There is a one-to-one mapping between ManagedRegister and register id.
     88 class X86_64ManagedRegister : public ManagedRegister {
     89  public:
     90   CpuRegister AsCpuRegister() const {
     91     CHECK(IsCpuRegister());
     92     return CpuRegister(static_cast<Register>(id_));
     93   }
     94 
     95   XmmRegister AsXmmRegister() const {
     96     CHECK(IsXmmRegister());
     97     return XmmRegister(static_cast<FloatRegister>(id_ - kNumberOfCpuRegIds));
     98   }
     99 
    100   X87Register AsX87Register() const {
    101     CHECK(IsX87Register());
    102     return static_cast<X87Register>(id_ -
    103                                     (kNumberOfCpuRegIds + kNumberOfXmmRegIds));
    104   }
    105 
    106   CpuRegister AsRegisterPairLow() const {
    107     CHECK(IsRegisterPair());
    108     // Appropriate mapping of register ids allows to use AllocIdLow().
    109     return FromRegId(AllocIdLow()).AsCpuRegister();
    110   }
    111 
    112   CpuRegister AsRegisterPairHigh() const {
    113     CHECK(IsRegisterPair());
    114     // Appropriate mapping of register ids allows to use AllocIdHigh().
    115     return FromRegId(AllocIdHigh()).AsCpuRegister();
    116   }
    117 
    118   bool IsCpuRegister() const {
    119     CHECK(IsValidManagedRegister());
    120     return (0 <= id_) && (id_ < kNumberOfCpuRegIds);
    121   }
    122 
    123   bool IsXmmRegister() const {
    124     CHECK(IsValidManagedRegister());
    125     const int test = id_ - kNumberOfCpuRegIds;
    126     return (0 <= test) && (test < kNumberOfXmmRegIds);
    127   }
    128 
    129   bool IsX87Register() const {
    130     CHECK(IsValidManagedRegister());
    131     const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds);
    132     return (0 <= test) && (test < kNumberOfX87RegIds);
    133   }
    134 
    135   bool IsRegisterPair() const {
    136     CHECK(IsValidManagedRegister());
    137     const int test = id_ -
    138         (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds);
    139     return (0 <= test) && (test < kNumberOfPairRegIds);
    140   }
    141 
    142   void Print(std::ostream& os) const;
    143 
    144   // Returns true if the two managed-registers ('this' and 'other') overlap.
    145   // Either managed-register may be the NoRegister. If both are the NoRegister
    146   // then false is returned.
    147   bool Overlaps(const X86_64ManagedRegister& other) const;
    148 
    149   static X86_64ManagedRegister FromCpuRegister(Register r) {
    150     CHECK_NE(r, kNoRegister);
    151     return FromRegId(r);
    152   }
    153 
    154   static X86_64ManagedRegister FromXmmRegister(FloatRegister r) {
    155     return FromRegId(r + kNumberOfCpuRegIds);
    156   }
    157 
    158   static X86_64ManagedRegister FromX87Register(X87Register r) {
    159     CHECK_NE(r, kNoX87Register);
    160     return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds);
    161   }
    162 
    163   static X86_64ManagedRegister FromRegisterPair(RegisterPair r) {
    164     CHECK_NE(r, kNoRegisterPair);
    165     return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds +
    166                           kNumberOfX87RegIds));
    167   }
    168 
    169  private:
    170   bool IsValidManagedRegister() const {
    171     return (0 <= id_) && (id_ < kNumberOfRegIds);
    172   }
    173 
    174   int RegId() const {
    175     CHECK(!IsNoRegister());
    176     return id_;
    177   }
    178 
    179   int AllocId() const {
    180     CHECK(IsValidManagedRegister() && !IsRegisterPair());
    181     CHECK_LT(id_, kNumberOfAllocIds);
    182     return id_;
    183   }
    184 
    185   int AllocIdLow() const;
    186   int AllocIdHigh() const;
    187 
    188   friend class ManagedRegister;
    189 
    190   explicit X86_64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {}
    191 
    192   static X86_64ManagedRegister FromRegId(int reg_id) {
    193     X86_64ManagedRegister reg(reg_id);
    194     CHECK(reg.IsValidManagedRegister());
    195     return reg;
    196   }
    197 };
    198 
    199 std::ostream& operator<<(std::ostream& os, const X86_64ManagedRegister& reg);
    200 
    201 }  // namespace x86_64
    202 
    203 inline x86_64::X86_64ManagedRegister ManagedRegister::AsX86_64() const {
    204   x86_64::X86_64ManagedRegister reg(id_);
    205   CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister());
    206   return reg;
    207 }
    208 
    209 }  // namespace art
    210 
    211 #endif  // ART_COMPILER_UTILS_X86_64_MANAGED_REGISTER_X86_64_H_
    212