managed_register_arm64.cc revision ed8dd492e43cbaaa435c4892447072c84dbaf2dc
1ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu/*
2ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * Copyright (C) 2014 The Android Open Source Project
3ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu *
4ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * Licensed under the Apache License, Version 2.0 (the "License");
5ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * you may not use this file except in compliance with the License.
6ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * You may obtain a copy of the License at
7ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu *
8ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu *      http://www.apache.org/licenses/LICENSE-2.0
9ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu *
10ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * Unless required by applicable law or agreed to in writing, software
11ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * distributed under the License is distributed on an "AS IS" BASIS,
12ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * See the License for the specific language governing permissions and
14ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu * limitations under the License.
15ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu */
16ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
17ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "managed_register_arm64.h"
18ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu#include "globals.h"
19ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
20ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescunamespace art {
21ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescunamespace arm64 {
22ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
23ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// TODO: Define convention
24ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//
25ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// Do not use APCS callee saved regs for now. Use:
26ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//  * [X0, X15]
27ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//  * [W0, W15]
28ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//  * [D0, D31]
29ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//  * [S0, S31]
30ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescustatic const int kNumberOfAvailableCoreRegisters = (X15 - X0) + 1;
31ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescustatic const int kNumberOfAvailableWRegisters = (W15 - W0) + 1;
32ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescustatic const int kNumberOfAvailableDRegisters = kNumberOfDRegisters;
33ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescustatic const int kNumberOfAvailableSRegisters = kNumberOfSRegisters;
34ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
35ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// Returns true if this managed-register overlaps the other managed-register.
36ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// GP Register Bank:
37ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//       31____0 W[n]
38ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// 63__________0 X[n]
39ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//
40ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// FP Register Bank:
41ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu//       31____0 S[n]
42ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// 63__________0 D[n]
43ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescubool Arm64ManagedRegister::Overlaps(const Arm64ManagedRegister& other) const {
44ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (IsNoRegister() || other.IsNoRegister()) return false;
45ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if ((IsGPRegister() && other.IsGPRegister()) ||
46ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu      (IsFPRegister() && other.IsFPRegister())) {
47ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    return (RegNo() == other.RegNo());
48ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
49ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return false;
50ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
51ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
52ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuint Arm64ManagedRegister::RegNo() const {
53ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  CHECK(!IsNoRegister());
54ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  int no;
55ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (IsCoreRegister()) {
56ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    if (IsStackPointer()) {
57ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu      no = static_cast<int>(X31);
58ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    } else {
59ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu      no = static_cast<int>(AsCoreRegister());
60ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    }
61ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsWRegister()) {
62ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = static_cast<int>(AsWRegister());
63ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsDRegister()) {
64ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = static_cast<int>(AsDRegister());
65ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsSRegister()) {
66ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = static_cast<int>(AsSRegister());
67ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else {
68ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = kNoRegister;
69ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
70ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return no;
71ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
72ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
73ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuint Arm64ManagedRegister::RegIdLow() const {
74ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  CHECK(IsCoreRegister() || IsDRegister());
75ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  int low = RegNo();
76ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (IsCoreRegister()) {
77ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    low += kNumberOfCoreRegIds;
78ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsDRegister()) {
79ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    low += kNumberOfCoreRegIds + kNumberOfWRegIds + kNumberOfDRegIds;
80ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
81ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return low;
82ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
83ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
84ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// FIXME: Find better naming.
85ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuint Arm64ManagedRegister::RegIdHigh() const {
86ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  CHECK(IsWRegister() || IsSRegister());
87ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  int high = RegNo();
88ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (IsSRegister()) {
89ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    high += kNumberOfCoreRegIds + kNumberOfWRegIds;
90ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
91ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return high;
92ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
93ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
94ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuvoid Arm64ManagedRegister::Print(std::ostream& os) const {
95ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (!IsValidManagedRegister()) {
96ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "No Register";
97ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsCoreRegister()) {
98ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "XCore: " << static_cast<int>(AsCoreRegister());
99ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsWRegister()) {
100ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "WCore: " << static_cast<int>(AsWRegister());
101ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsDRegister()) {
102ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "DRegister: " << static_cast<int>(AsDRegister());
103ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsSRegister()) {
104ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "SRegister: " << static_cast<int>(AsSRegister());
105ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else {
106ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "??: " << RegId();
107ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
108ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
109ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
110ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescustd::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg) {
111ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  reg.Print(os);
112ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return os;
113ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
114ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
115ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}  // namespace arm64
116ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}  // namespace art
117