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 2057943810cfc789da890d73621741729da5feaaf8Andreas Gampe#include <android-base/logging.h> 2157943810cfc789da890d73621741729da5feaaf8Andreas Gampe 220f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "constants_arm.h" 234fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/dwarf/register.h" 24166db04e259ca51838c311891598664deeed85adIan Rogers#include "utils/managed_register.h" 25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2612e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov// TODO(VIXL): Make VIXL compile with -Wshadow. 2712e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov#pragma GCC diagnostic push 2812e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov#pragma GCC diagnostic ignored "-Wshadow" 2912e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov#include "aarch32/macro-assembler-aarch32.h" 3012e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov#pragma GCC diagnostic pop 3112e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov 32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm { 34b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Values for register pairs. 36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersenum RegisterPair { 37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R0_R1 = 0, 38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R2_R3 = 1, 39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R4_R5 = 2, 40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers R6_R7 = 3, 417a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers R1_R2 = 4, // Dalvik style passing 427a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers kNumberOfRegisterPairs = 5, 43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNoRegisterPair = -1, 44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const RegisterPair& reg); 47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCoreRegIds = kNumberOfCoreRegisters; 49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCoreAllocIds = kNumberOfCoreRegisters; 50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfSRegIds = kNumberOfSRegisters; 52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfSAllocIds = kNumberOfSRegisters; 53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfDRegIds = kNumberOfDRegisters; 55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfOverlappingDRegIds = kNumberOfOverlappingDRegisters; 56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfDAllocIds = kNumberOfDRegIds - kNumberOfOverlappingDRegIds; 57b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 58b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfPairRegIds = kNumberOfRegisterPairs; 59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfRegIds = kNumberOfCoreRegIds + kNumberOfSRegIds + 61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfDRegIds + kNumberOfPairRegIds; 62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfAllocIds = 63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfCoreAllocIds + kNumberOfSAllocIds + kNumberOfDAllocIds; 64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register ids map: 66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [0..R[ core registers (enum Register) 67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [R..S[ single precision VFP registers (enum SRegister) 68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [S..D[ double precision VFP registers (enum DRegister) 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [D..P[ core register pairs (enum RegisterPair) 70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where 71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// R = kNumberOfCoreRegIds 72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// S = R + kNumberOfSRegIds 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// D = S + kNumberOfDRegIds 74b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// P = D + kNumberOfRegisterPairs 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Allocation ids map: 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [0..R[ core registers (enum Register) 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [R..S[ single precision VFP registers (enum SRegister) 79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [S..N[ non-overlapping double precision VFP registers (16-31 in enum 80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// DRegister, VFPv3-D32 only) 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// R = kNumberOfCoreAllocIds 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// S = R + kNumberOfSAllocIds 84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// N = S + kNumberOfDAllocIds 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// An instance of class 'ManagedRegister' represents a single ARM register or a 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// pair of core ARM registers (enum RegisterPair). A single register is either a 89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// core register (enum Register), a VFP single precision register 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// (enum SRegister), or a VFP double precision register (enum DRegister). 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// 'ManagedRegister::NoRegister()' returns an invalid ManagedRegister. 92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// There is a one-to-one mapping between ManagedRegister and register id. 932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass ArmManagedRegister : public ManagedRegister { 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 953224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr Register AsCoreRegister() const { 96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsCoreRegister()); 97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<Register>(id_); 98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 10012e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov vixl::aarch32::Register AsVIXLRegister() const { 10112e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov CHECK(IsCoreRegister()); 10212e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov return vixl::aarch32::Register(id_); 10312e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov } 10412e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov 1053224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr SRegister AsSRegister() const { 106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsSRegister()); 107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<SRegister>(id_ - kNumberOfCoreRegIds); 108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 11012e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov vixl::aarch32::SRegister AsVIXLSRegister() const { 11112e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov CHECK(IsSRegister()); 11212e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov return vixl::aarch32::SRegister(id_ - kNumberOfCoreRegIds); 11312e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov } 11412e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov 1153224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr DRegister AsDRegister() const { 116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsDRegister()); 117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfSRegIds); 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 12012e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov vixl::aarch32::DRegister AsVIXLDRegister() const { 12112e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov CHECK(IsDRegister()); 12212e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov return vixl::aarch32::DRegister(id_ - kNumberOfCoreRegIds - kNumberOfSRegIds); 12312e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov } 12412e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov 1253224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr SRegister AsOverlappingDRegisterLow() const { 126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsOverlappingDRegister()); 127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DRegister d_reg = AsDRegister(); 128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<SRegister>(d_reg * 2); 129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1313224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr SRegister AsOverlappingDRegisterHigh() const { 132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsOverlappingDRegister()); 133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DRegister d_reg = AsDRegister(); 134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<SRegister>(d_reg * 2 + 1); 135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1373224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr RegisterPair AsRegisterPair() const { 138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg_low = AsRegisterPairLow(); 1407a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers if (reg_low == R1) { 1417a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return R1_R2; 1427a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else { 1437a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return static_cast<RegisterPair>(reg_low / 2); 1447a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } 145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1473224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr Register AsRegisterPairLow() const { 148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Appropriate mapping of register ids allows to use AllocIdLow(). 150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(AllocIdLow()).AsCoreRegister(); 151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15312e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov vixl::aarch32::Register AsVIXLRegisterPairLow() const { 15412e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov return vixl::aarch32::Register(AsRegisterPairLow()); 15512e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov } 15612e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov 1573224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr Register AsRegisterPairHigh() const { 158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Appropriate mapping of register ids allows to use AllocIdHigh(). 160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(AllocIdHigh()).AsCoreRegister(); 161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 16312e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov vixl::aarch32::Register AsVIXLRegisterPairHigh() const { 16412e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov return vixl::aarch32::Register(AsRegisterPairHigh()); 16512e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov } 16612e097c84cef710fa4f254b1811ff70b876e9e9aArtem Serov 1673224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsCoreRegister() const { 168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= id_) && (id_ < kNumberOfCoreRegIds); 170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1723224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsSRegister() const { 173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - kNumberOfCoreRegIds; 175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfSRegIds); 176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1783224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsDRegister() const { 179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); 181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfDRegIds); 182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Returns true if this DRegister overlaps SRegisters. 1853224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsOverlappingDRegister() const { 186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); 188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfOverlappingDRegIds); 189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1913224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsRegisterPair() const { 192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = 194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds + kNumberOfDRegIds); 195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfPairRegIds); 196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1983224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsSameType(ArmManagedRegister test) const { 199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister() && test.IsValidManagedRegister()); 200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return 201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsCoreRegister() && test.IsCoreRegister()) || 202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsSRegister() && test.IsSRegister()) || 203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsDRegister() && test.IsDRegister()) || 204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (IsRegisterPair() && test.IsRegisterPair()); 205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Returns true if the two managed-registers ('this' and 'other') overlap. 209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Either managed-register may be the NoRegister. If both are the NoRegister 210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // then false is returned. 2112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool Overlaps(const ArmManagedRegister& other) const; 212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void Print(std::ostream& os) const; 214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2153224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromCoreRegister(Register r) { 216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoRegister); 217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r); 218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2203224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromSRegister(SRegister r) { 221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoSRegister); 222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + kNumberOfCoreRegIds); 223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2253224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromDRegister(DRegister r) { 226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoDRegister); 227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfSRegIds)); 228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2303224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromRegisterPair(RegisterPair r) { 231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoRegisterPair); 232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + (kNumberOfCoreRegIds + 233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfSRegIds + kNumberOfDRegIds)); 234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Return a RegisterPair consisting of Register r_low and r_low + 1. 2373224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromCoreRegisterPair(Register r_low) { 2387a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers if (r_low != R1) { // not the dalvik special case 2397a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK_NE(r_low, kNoRegister); 2407a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK_EQ(0, (r_low % 2)); 2417a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers const int r = r_low / 2; 2427a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK_LT(r, kNumberOfPairRegIds); 2437a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return FromRegisterPair(static_cast<RegisterPair>(r)); 2447a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else { 2457a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers return FromRegisterPair(R1_R2); 2467a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } 247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Return a DRegister overlapping SRegister r_low and r_low + 1. 2503224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromSRegisterPair(SRegister r_low) { 251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r_low, kNoSRegister); 252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(0, (r_low % 2)); 253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int r = r_low / 2; 254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_LT(r, kNumberOfOverlappingDRegIds); 255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromDRegister(static_cast<DRegister>(r)); 256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 2593224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko constexpr bool IsValidManagedRegister() const { 260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= id_) && (id_ < kNumberOfRegIds); 261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 263b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int RegId() const { 264b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(!IsNoRegister()); 265b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return id_; 266b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 267b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 268b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocId() const { 269b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister() && 270b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers !IsOverlappingDRegister() && !IsRegisterPair()); 271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int r = id_; 272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if ((kNumberOfDAllocIds > 0) && IsDRegister()) { // VFPv3-D32 only. 273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers r -= kNumberOfOverlappingDRegIds; 274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 275b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_LT(r, kNumberOfAllocIds); 276b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return r; 277b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 278b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 279b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocIdLow() const; 280b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocIdHigh() const; 281b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers friend class ManagedRegister; 2832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2843224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko explicit constexpr ArmManagedRegister(int reg_id) : ManagedRegister(reg_id) {} 2852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2863224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Marko static constexpr ArmManagedRegister FromRegId(int reg_id) { 2872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister reg(reg_id); 288b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(reg.IsValidManagedRegister()); 289b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return reg; 290b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 291b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 292b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersstd::ostream& operator<<(std::ostream& os, const ArmManagedRegister& reg); 2942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace arm 2962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 2973224838dfe9c95330ad963286f2c47e9546d3b5cVladimir Markoconstexpr inline arm::ArmManagedRegister ManagedRegister::AsArm() const { 2982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers arm::ArmManagedRegister reg(id_); 2992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); 3002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return reg; 3012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 302b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 303b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 304b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 305166db04e259ca51838c311891598664deeed85adIan Rogers#endif // ART_COMPILER_UTILS_ARM_MANAGED_REGISTER_ARM_H_ 306