managed_register_x86_64.h revision fca82208f7128fcda09b6a4743199308332558a2
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 23namespace art { 24namespace 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. 29enum 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 44std::ostream& operator<<(std::ostream& os, const RegisterPair& reg); 45 46const int kNumberOfCpuRegIds = kNumberOfCpuRegisters; 47const int kNumberOfCpuAllocIds = kNumberOfCpuRegisters; 48 49const int kNumberOfXmmRegIds = kNumberOfXmmRegisters; 50const int kNumberOfXmmAllocIds = kNumberOfXmmRegisters; 51 52const int kNumberOfX87RegIds = kNumberOfX87Registers; 53const int kNumberOfX87AllocIds = kNumberOfX87Registers; 54 55const int kNumberOfPairRegIds = kNumberOfRegisterPairs; 56 57const int kNumberOfRegIds = kNumberOfCpuRegIds + kNumberOfXmmRegIds + 58 kNumberOfX87RegIds + kNumberOfPairRegIds; 59const 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. 88class X86_64ManagedRegister : public ManagedRegister { 89 public: 90 ByteRegister AsByteRegister() const { 91 CHECK(IsCpuRegister()); 92 CHECK_LT(AsCpuRegister(), RSP); // RSP, RBP, ESI and RDI cannot be encoded as byte registers. 93 return static_cast<ByteRegister>(id_); 94 } 95 96 Register AsCpuRegister() const { 97 CHECK(IsCpuRegister()); 98 return static_cast<Register>(id_); 99 } 100 101 XmmRegister AsXmmRegister() const { 102 CHECK(IsXmmRegister()); 103 return static_cast<XmmRegister>(id_ - kNumberOfCpuRegIds); 104 } 105 106 X87Register AsX87Register() const { 107 CHECK(IsX87Register()); 108 return static_cast<X87Register>(id_ - 109 (kNumberOfCpuRegIds + kNumberOfXmmRegIds)); 110 } 111 112 Register AsRegisterPairLow() const { 113 CHECK(IsRegisterPair()); 114 // Appropriate mapping of register ids allows to use AllocIdLow(). 115 return FromRegId(AllocIdLow()).AsCpuRegister(); 116 } 117 118 Register AsRegisterPairHigh() const { 119 CHECK(IsRegisterPair()); 120 // Appropriate mapping of register ids allows to use AllocIdHigh(). 121 return FromRegId(AllocIdHigh()).AsCpuRegister(); 122 } 123 124 bool IsCpuRegister() const { 125 CHECK(IsValidManagedRegister()); 126 return (0 <= id_) && (id_ < kNumberOfCpuRegIds); 127 } 128 129 bool IsXmmRegister() const { 130 CHECK(IsValidManagedRegister()); 131 const int test = id_ - kNumberOfCpuRegIds; 132 return (0 <= test) && (test < kNumberOfXmmRegIds); 133 } 134 135 bool IsX87Register() const { 136 CHECK(IsValidManagedRegister()); 137 const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds); 138 return (0 <= test) && (test < kNumberOfX87RegIds); 139 } 140 141 bool IsRegisterPair() const { 142 CHECK(IsValidManagedRegister()); 143 const int test = id_ - 144 (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds); 145 return (0 <= test) && (test < kNumberOfPairRegIds); 146 } 147 148 void Print(std::ostream& os) const; 149 150 // Returns true if the two managed-registers ('this' and 'other') overlap. 151 // Either managed-register may be the NoRegister. If both are the NoRegister 152 // then false is returned. 153 bool Overlaps(const X86_64ManagedRegister& other) const; 154 155 static X86_64ManagedRegister FromCpuRegister(Register r) { 156 CHECK_NE(r, kNoRegister); 157 return FromRegId(r); 158 } 159 160 static X86_64ManagedRegister FromXmmRegister(XmmRegister r) { 161 CHECK_NE(r, kNoXmmRegister); 162 return FromRegId(r + kNumberOfCpuRegIds); 163 } 164 165 static X86_64ManagedRegister FromX87Register(X87Register r) { 166 CHECK_NE(r, kNoX87Register); 167 return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds); 168 } 169 170 static X86_64ManagedRegister FromRegisterPair(RegisterPair r) { 171 CHECK_NE(r, kNoRegisterPair); 172 return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 173 kNumberOfX87RegIds)); 174 } 175 176 private: 177 bool IsValidManagedRegister() const { 178 return (0 <= id_) && (id_ < kNumberOfRegIds); 179 } 180 181 int RegId() const { 182 CHECK(!IsNoRegister()); 183 return id_; 184 } 185 186 int AllocId() const { 187 CHECK(IsValidManagedRegister() && !IsRegisterPair()); 188 CHECK_LT(id_, kNumberOfAllocIds); 189 return id_; 190 } 191 192 int AllocIdLow() const; 193 int AllocIdHigh() const; 194 195 friend class ManagedRegister; 196 197 explicit X86_64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} 198 199 static X86_64ManagedRegister FromRegId(int reg_id) { 200 X86_64ManagedRegister reg(reg_id); 201 CHECK(reg.IsValidManagedRegister()); 202 return reg; 203 } 204}; 205 206std::ostream& operator<<(std::ostream& os, const X86_64ManagedRegister& reg); 207 208} // namespace x86_64 209 210inline x86_64::X86_64ManagedRegister ManagedRegister::AsX86_64() const { 211 x86_64::X86_64ManagedRegister reg(id_); 212 CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); 213 return reg; 214} 215 216} // namespace art 217 218#endif // ART_COMPILER_UTILS_X86_64_MANAGED_REGISTER_X86_64_H_ 219