1 /* 2 * Copyright (C) 2011 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_MANAGED_REGISTER_H_ 18 #define ART_COMPILER_UTILS_MANAGED_REGISTER_H_ 19 20 #include <type_traits> 21 #include <vector> 22 23 #include "base/value_object.h" 24 25 namespace art { 26 27 namespace arm { 28 class ArmManagedRegister; 29 } // namespace arm 30 namespace arm64 { 31 class Arm64ManagedRegister; 32 } // namespace arm64 33 namespace mips { 34 class MipsManagedRegister; 35 } // namespace mips 36 namespace mips64 { 37 class Mips64ManagedRegister; 38 } // namespace mips64 39 40 namespace x86 { 41 class X86ManagedRegister; 42 } // namespace x86 43 44 namespace x86_64 { 45 class X86_64ManagedRegister; 46 } // namespace x86_64 47 48 class ManagedRegister : public ValueObject { 49 public: 50 // ManagedRegister is a value class. There exists no method to change the 51 // internal state. We therefore allow a copy constructor and an 52 // assignment-operator. 53 constexpr ManagedRegister(const ManagedRegister& other) = default; 54 55 ManagedRegister& operator=(const ManagedRegister& other) = default; 56 57 constexpr arm::ArmManagedRegister AsArm() const; 58 constexpr arm64::Arm64ManagedRegister AsArm64() const; 59 constexpr mips::MipsManagedRegister AsMips() const; 60 constexpr mips64::Mips64ManagedRegister AsMips64() const; 61 constexpr x86::X86ManagedRegister AsX86() const; 62 constexpr x86_64::X86_64ManagedRegister AsX86_64() const; 63 64 // It is valid to invoke Equals on and with a NoRegister. 65 constexpr bool Equals(const ManagedRegister& other) const { 66 return id_ == other.id_; 67 } 68 69 constexpr bool IsNoRegister() const { 70 return id_ == kNoRegister; 71 } 72 73 static constexpr ManagedRegister NoRegister() { 74 return ManagedRegister(); 75 } 76 77 constexpr int RegId() const { return id_; } 78 explicit constexpr ManagedRegister(int reg_id) : id_(reg_id) { } 79 80 protected: 81 static const int kNoRegister = -1; 82 83 constexpr ManagedRegister() : id_(kNoRegister) { } 84 85 int id_; 86 }; 87 88 static_assert(std::is_trivially_copyable<ManagedRegister>::value, 89 "ManagedRegister should be trivially copyable"); 90 91 class ManagedRegisterSpill : public ManagedRegister { 92 public: 93 // ManagedRegisterSpill contains information about data type size and location in caller frame 94 // These additional attributes could be defined by calling convention (EntrySpills) 95 ManagedRegisterSpill(const ManagedRegister& other, uint32_t size, uint32_t spill_offset) 96 : ManagedRegister(other), size_(size), spill_offset_(spill_offset) { } 97 98 explicit ManagedRegisterSpill(const ManagedRegister& other) 99 : ManagedRegister(other), size_(-1), spill_offset_(-1) { } 100 101 ManagedRegisterSpill(const ManagedRegister& other, int32_t size) 102 : ManagedRegister(other), size_(size), spill_offset_(-1) { } 103 104 int32_t getSpillOffset() { 105 return spill_offset_; 106 } 107 108 int32_t getSize() { 109 return size_; 110 } 111 112 private: 113 int32_t size_; 114 int32_t spill_offset_; 115 }; 116 117 class ManagedRegisterEntrySpills : public std::vector<ManagedRegisterSpill> { 118 public: 119 // The ManagedRegister does not have information about size and offset. 120 // In this case it's size and offset determined by BuildFrame (assembler) 121 void push_back(ManagedRegister x) { 122 ManagedRegisterSpill spill(x); 123 std::vector<ManagedRegisterSpill>::push_back(spill); 124 } 125 126 void push_back(ManagedRegister x, int32_t size) { 127 ManagedRegisterSpill spill(x, size); 128 std::vector<ManagedRegisterSpill>::push_back(spill); 129 } 130 131 void push_back(ManagedRegisterSpill x) { 132 std::vector<ManagedRegisterSpill>::push_back(x); 133 } 134 private: 135 }; 136 137 } // namespace art 138 139 #endif // ART_COMPILER_UTILS_MANAGED_REGISTER_H_ 140