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]
3037c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames// static const int kNumberOfAvailableXRegisters = (X15 - X0) + 1;
31719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers// static const int kNumberOfAvailableWRegisters = (W15 - W0) + 1;
32719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers// static const int kNumberOfAvailableDRegisters = kNumberOfDRegisters;
33719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers// static 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;
45a304f97c97d38af73afe6b49259ac4faf0902123Alexandre Rames  return (IsGPRegister() == other.IsGPRegister()) && (RegNo() == other.RegNo());
46ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
47ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
48ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuint Arm64ManagedRegister::RegNo() const {
49ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  CHECK(!IsNoRegister());
50ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  int no;
5137c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames  if (IsXRegister()) {
5237c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames    no = static_cast<int>(AsXRegister());
53ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsWRegister()) {
54ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = static_cast<int>(AsWRegister());
55ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsDRegister()) {
56ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = static_cast<int>(AsDRegister());
57ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsSRegister()) {
58ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = static_cast<int>(AsSRegister());
59ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else {
60ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    no = kNoRegister;
61ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
62ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return no;
63ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
64ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
65ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuint Arm64ManagedRegister::RegIdLow() const {
6637c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames  CHECK(IsXRegister() || IsDRegister());
67ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  int low = RegNo();
6837c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames  if (IsXRegister()) {
6937c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames    low += kNumberOfXRegIds;
70ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsDRegister()) {
7137c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames    low += kNumberOfXRegIds + kNumberOfWRegIds + kNumberOfDRegIds;
72ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
73ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return low;
74ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
75ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
76ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu// FIXME: Find better naming.
77ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuint Arm64ManagedRegister::RegIdHigh() const {
78ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  CHECK(IsWRegister() || IsSRegister());
79ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  int high = RegNo();
80ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (IsSRegister()) {
8137c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames    high += kNumberOfXRegIds + kNumberOfWRegIds;
82ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
83ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return high;
84ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
85ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
86ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuvoid Arm64ManagedRegister::Print(std::ostream& os) const {
87ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  if (!IsValidManagedRegister()) {
88ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "No Register";
8937c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames  } else if (IsXRegister()) {
9037c92df53979f9f6ab83155ab9521d554d717161Alexandre Rames    os << "XCore: " << static_cast<int>(AsXRegister());
91ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsWRegister()) {
92ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "WCore: " << static_cast<int>(AsWRegister());
93ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsDRegister()) {
94ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "DRegister: " << static_cast<int>(AsDRegister());
95ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else if (IsSRegister()) {
96ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "SRegister: " << static_cast<int>(AsSRegister());
97ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  } else {
98ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu    os << "??: " << RegId();
99ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  }
100ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
101ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
102ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescustd::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg) {
103ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  reg.Print(os);
104ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  return os;
105ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
106ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu
107ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}  // namespace arm64
108ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}  // namespace art
109