12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 17166db04e259ca51838c311891598664deeed85adIan Rogers#ifndef ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_ 18166db04e259ca51838c311891598664deeed85adIan Rogers#define ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_ 19b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 210f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "constants_arm.h" 224fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/register.h" 23166db04e259ca51838c311891598664deeed85adIan Rogers#include "utils/managed_register.h" 24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm { 27b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 28b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Values for register pairs. 29b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersenum RegisterPair { 30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R0_R1 = 0, 31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R2_R3 = 1, 32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R4_R5 = 2, 33b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R6_R7 = 3, 347a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers R1_R2 = 4, // Dalvik style passing 357a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers kNumberOfRegisterPairs = 5, 36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNoRegisterPair = -1, 37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const RegisterPair& reg); 40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCoreRegIds = kNumberOfCoreRegisters; 42b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCoreAllocIds = kNumberOfCoreRegisters; 43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfSRegIds = kNumberOfSRegisters; 45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfSAllocIds = kNumberOfSRegisters; 46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfDRegIds = kNumberOfDRegisters; 48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfOverlappingDRegIds = kNumberOfOverlappingDRegisters; 49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfDAllocIds = kNumberOfDRegIds - kNumberOfOverlappingDRegIds; 50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfPairRegIds = kNumberOfRegisterPairs; 52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfRegIds = kNumberOfCoreRegIds + kNumberOfSRegIds + 54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfDRegIds + kNumberOfPairRegIds; 55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfAllocIds = 56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfCoreAllocIds + kNumberOfSAllocIds + kNumberOfDAllocIds; 57b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 58b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register ids map: 59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [0..R[ core registers (enum Register) 60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [R..S[ single precision VFP registers (enum SRegister) 61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [S..D[ double precision VFP registers (enum DRegister) 62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [D..P[ core register pairs (enum RegisterPair) 63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where 64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// R = kNumberOfCoreRegIds 65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// S = R + kNumberOfSRegIds 66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// D = S + kNumberOfDRegIds 67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// P = D + kNumberOfRegisterPairs 68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Allocation ids map: 70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [0..R[ core registers (enum Register) 71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [R..S[ single precision VFP registers (enum SRegister) 72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [S..N[ non-overlapping double precision VFP registers (16-31 in enum 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// DRegister, VFPv3-D32 only) 74b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// R = kNumberOfCoreAllocIds 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// S = R + kNumberOfSAllocIds 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// N = S + kNumberOfDAllocIds 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// An instance of class 'ManagedRegister' represents a single ARM register or a 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// pair of core ARM registers (enum RegisterPair). A single register is either a 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// core register (enum Register), a VFP single precision register 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// (enum SRegister), or a VFP double precision register (enum DRegister). 84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// 'ManagedRegister::NoRegister()' returns an invalid ManagedRegister. 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// There is a one-to-one mapping between ManagedRegister and register id. 862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass ArmManagedRegister : public ManagedRegister { 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register AsCoreRegister() const { 89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsCoreRegister()); 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<Register>(id_); 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SRegister AsSRegister() const { 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsSRegister()); 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<SRegister>(id_ - kNumberOfCoreRegIds); 96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DRegister AsDRegister() const { 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsDRegister()); 100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfSRegIds); 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SRegister AsOverlappingDRegisterLow() const { 104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsOverlappingDRegister()); 105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DRegister d_reg = AsDRegister(); 106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<SRegister>(d_reg * 2); 107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SRegister AsOverlappingDRegisterHigh() const { 110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsOverlappingDRegister()); 111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DRegister d_reg = AsDRegister(); 112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<SRegister>(d_reg * 2 + 1); 113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers RegisterPair AsRegisterPair() const { 116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg_low = AsRegisterPairLow(); 1187a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers if (reg_low == R1) { 1197a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return R1_R2; 1207a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else { 1217a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return static_cast<RegisterPair>(reg_low / 2); 1227a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } 123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register AsRegisterPairLow() const { 126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Appropriate mapping of register ids allows to use AllocIdLow(). 128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(AllocIdLow()).AsCoreRegister(); 129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register AsRegisterPairHigh() const { 132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Appropriate mapping of register ids allows to use AllocIdHigh(). 134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(AllocIdHigh()).AsCoreRegister(); 135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCoreRegister() const { 138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= id_) && (id_ < kNumberOfCoreRegIds); 140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsSRegister() const { 143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - kNumberOfCoreRegIds; 145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfSRegIds); 146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsDRegister() const { 149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); 151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfDRegIds); 152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Returns true if this DRegister overlaps SRegisters. 155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsOverlappingDRegister() const { 156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); 158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfOverlappingDRegIds); 159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsRegisterPair() const { 162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = 164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds + kNumberOfDRegIds); 165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfPairRegIds); 166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool IsSameType(ArmManagedRegister test) const { 169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister() && test.IsValidManagedRegister()); 170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return 171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsCoreRegister() && test.IsCoreRegister()) || 172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsSRegister() && test.IsSRegister()) || 173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsDRegister() && test.IsDRegister()) || 174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsRegisterPair() && test.IsRegisterPair()); 175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Returns true if the two managed-registers ('this' and 'other') overlap. 179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Either managed-register may be the NoRegister. If both are the NoRegister 180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // then false is returned. 1812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool Overlaps(const ArmManagedRegister& other) const; 182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void Print(std::ostream& os) const; 184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromCoreRegister(Register r) { 186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoRegister); 187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r); 188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromSRegister(SRegister r) { 191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoSRegister); 192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + kNumberOfCoreRegIds); 193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromDRegister(DRegister r) { 196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoDRegister); 197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfSRegIds)); 198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromRegisterPair(RegisterPair r) { 201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoRegisterPair); 202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + (kNumberOfCoreRegIds + 203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfSRegIds + kNumberOfDRegIds)); 204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Return a RegisterPair consisting of Register r_low and r_low + 1. 2072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromCoreRegisterPair(Register r_low) { 2087a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers if (r_low != R1) { // not the dalvik special case 2097a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK_NE(r_low, kNoRegister); 2107a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK_EQ(0, (r_low % 2)); 2117a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers const int r = r_low / 2; 2127a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK_LT(r, kNumberOfPairRegIds); 2137a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return FromRegisterPair(static_cast<RegisterPair>(r)); 2147a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else { 2157a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return FromRegisterPair(R1_R2); 2167a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } 217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Return a DRegister overlapping SRegister r_low and r_low + 1. 2202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromSRegisterPair(SRegister r_low) { 221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r_low, kNoSRegister); 222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(0, (r_low % 2)); 223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int r = r_low / 2; 224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_LT(r, kNumberOfOverlappingDRegIds); 225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromDRegister(static_cast<DRegister>(r)); 226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsValidManagedRegister() const { 230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= id_) && (id_ < kNumberOfRegIds); 231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int RegId() const { 234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(!IsNoRegister()); 235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return id_; 236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocId() const { 239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister() && 240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers !IsOverlappingDRegister() && !IsRegisterPair()); 241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int r = id_; 242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if ((kNumberOfDAllocIds > 0) && IsDRegister()) { // VFPv3-D32 only. 243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers r -= kNumberOfOverlappingDRegIds; 244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_LT(r, kNumberOfAllocIds); 246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return r; 247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocIdLow() const; 250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocIdHigh() const; 251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers friend class ManagedRegister; 2532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 254a51a3dd5603daf3d368b7735067e1d9eb54c4c40Elliott Hughes explicit ArmManagedRegister(int reg_id) : ManagedRegister(reg_id) {} 2552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static ArmManagedRegister FromRegId(int reg_id) { 2572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister reg(reg_id); 258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(reg.IsValidManagedRegister()); 259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return reg; 260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersstd::ostream& operator<<(std::ostream& os, const ArmManagedRegister& reg); 2642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace arm 2662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline arm::ArmManagedRegister ManagedRegister::AsArm() const { 2682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers arm::ArmManagedRegister reg(id_); 2692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); 2702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return reg; 2712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 275166db04e259ca51838c311891598664deeed85adIan Rogers#endif // ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_ 276