Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014 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_DEX_REG_STORAGE_H_ |
| 18 | #define ART_COMPILER_DEX_REG_STORAGE_H_ |
| 19 | |
| 20 | |
| 21 | namespace art { |
| 22 | |
| 23 | /* |
| 24 | * Representation of the physical register, register pair or vector holding a Dalvik value. |
| 25 | * The basic configuration of the storage (i.e. solo reg, pair, vector) is common across all |
| 26 | * targets, but the encoding of the actual storage element is target independent. |
| 27 | * |
| 28 | * The two most-significant bits describe the basic shape of the storage, while meaning of the |
| 29 | * lower 14 bits depends on the shape: |
| 30 | * |
| 31 | * [PW] |
| 32 | * P: 0 -> pair, 1 -> solo (or vector) |
| 33 | * W: 1 -> 64 bits, 0 -> 32 bits |
| 34 | * |
| 35 | * [00] [xxxxxxxxxxxxxx] Invalid (typically all zeros) |
| 36 | * [01] [HHHHHHH] [LLLLLLL] 64-bit storage, composed of 2 32-bit registers |
| 37 | * [10] [0] [xxxxxx] [RRRRRRR] 32-bit solo register |
| 38 | * [11] [0] [xxxxxx] [RRRRRRR] 64-bit solo register |
| 39 | * [10] [1] [xxxxxx] [VVVVVVV] 32-bit vector storage |
| 40 | * [11] [1] [xxxxxx] [VVVVVVV] 64-bit vector storage |
| 41 | * |
| 42 | * x - don't care |
| 43 | * L - low register number of a pair |
| 44 | * H - high register number of a pair |
| 45 | * R - register number of a solo reg |
| 46 | * V - vector description |
| 47 | * |
| 48 | * Note that in all non-invalid cases, the low 7 bits must be sufficient to describe |
| 49 | * whether the storage element is floating point (see IsFloatReg()). |
| 50 | * |
| 51 | */ |
| 52 | |
| 53 | class RegStorage { |
| 54 | public: |
| 55 | enum RegStorageKind { |
| 56 | kInvalid = 0x0000, |
| 57 | k64BitPair = 0x4000, |
| 58 | k32BitSolo = 0x8000, |
| 59 | k64BitSolo = 0xc000, |
| 60 | k32BitVector = 0xa000, |
| 61 | k64BitVector = 0xe000, |
| 62 | kPairMask = 0x8000, |
| 63 | kPair = 0x0000, |
| 64 | kSizeMask = 0x4000, |
| 65 | k64Bit = 0x4000, |
| 66 | k32Bit = 0x0000, |
| 67 | kVectorMask = 0xa000, |
| 68 | kVector = 0xa000, |
| 69 | kSolo = 0x8000, |
| 70 | kShapeMask = 0xc000, |
| 71 | kKindMask = 0xe000 |
| 72 | }; |
| 73 | |
| 74 | static const uint16_t kRegValMask = 0x007f; |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 75 | static const uint16_t kInvalidRegVal = 0x007f; |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 76 | static const uint16_t kHighRegShift = 7; |
| 77 | static const uint16_t kHighRegMask = kRegValMask << kHighRegShift; |
| 78 | |
| 79 | RegStorage(RegStorageKind rs_kind, int reg) { |
| 80 | DCHECK_NE(rs_kind & kShapeMask, kInvalid); |
| 81 | DCHECK_NE(rs_kind & kShapeMask, k64BitPair); |
| 82 | DCHECK_EQ(rs_kind & ~kKindMask, 0); |
| 83 | DCHECK_EQ(reg & ~kRegValMask, 0); |
| 84 | reg_ = rs_kind | reg; |
| 85 | } |
| 86 | RegStorage(RegStorageKind rs_kind, int low_reg, int high_reg) { |
| 87 | DCHECK_EQ(rs_kind, k64BitPair); |
| 88 | DCHECK_EQ(low_reg & ~kRegValMask, 0); |
| 89 | DCHECK_EQ(high_reg & ~kRegValMask, 0); |
| 90 | reg_ = rs_kind | (high_reg << kHighRegShift) | low_reg; |
| 91 | } |
| 92 | explicit RegStorage(uint16_t val) : reg_(val) {} |
| 93 | RegStorage() : reg_(kInvalid) {} |
| 94 | ~RegStorage() {} |
| 95 | |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 96 | bool operator==(const RegStorage rhs) const { |
| 97 | return (reg_ == rhs.GetRawBits()); |
| 98 | } |
| 99 | |
| 100 | bool operator!=(const RegStorage rhs) const { |
| 101 | return (reg_ != rhs.GetRawBits()); |
| 102 | } |
| 103 | |
| 104 | bool Valid() const { |
| 105 | return ((reg_ & kShapeMask) != kInvalid); |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | bool Is32Bit() const { |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 109 | return ((reg_ & kSizeMask) == k32Bit); |
| 110 | } |
| 111 | |
| 112 | bool Is64Bit() const { |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 113 | return ((reg_ & kSizeMask) == k64Bit); |
| 114 | } |
| 115 | |
| 116 | bool IsPair() const { |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 117 | return ((reg_ & kPairMask) == kPair); |
| 118 | } |
| 119 | |
| 120 | bool IsSolo() const { |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 121 | return ((reg_ & kVectorMask) == kSolo); |
| 122 | } |
| 123 | |
| 124 | bool IsVector() const { |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 125 | return ((reg_ & kVectorMask) == kVector); |
| 126 | } |
| 127 | |
| 128 | // Used to retrieve either the low register of a pair, or the only register. |
| 129 | int GetReg() const { |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 130 | DCHECK(!IsPair()); |
| 131 | return Valid() ? (reg_ & kRegValMask) : kInvalidRegVal; |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | void SetReg(int reg) { |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 135 | DCHECK(Valid()); |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 136 | reg_ = (reg_ & ~kRegValMask) | reg; |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 137 | } |
| 138 | |
| 139 | void SetLowReg(int reg) { |
| 140 | DCHECK(IsPair()); |
| 141 | reg_ = (reg_ & ~kRegValMask) | reg; |
| 142 | } |
| 143 | |
| 144 | // Retrieve the least significant register of a pair. |
| 145 | int GetLowReg() const { |
| 146 | DCHECK(IsPair()); |
| 147 | return (reg_ & kRegValMask); |
| 148 | } |
| 149 | |
| 150 | // Create a stand-alone RegStorage from the low reg of a pair. |
| 151 | RegStorage GetLow() const { |
| 152 | DCHECK(IsPair()); |
| 153 | return RegStorage(k32BitSolo, reg_ & kRegValMask); |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | // Retrieve the most significant register of a pair. |
| 157 | int GetHighReg() const { |
| 158 | DCHECK(IsPair()); |
| 159 | return (reg_ & kHighRegMask) >> kHighRegShift; |
| 160 | } |
| 161 | |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 162 | // Create a stand-alone RegStorage from the high reg of a pair. |
| 163 | RegStorage GetHigh() const { |
| 164 | DCHECK(IsPair()); |
| 165 | return RegStorage(k32BitSolo, (reg_ & kHighRegMask) >> kHighRegShift); |
| 166 | } |
| 167 | |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 168 | void SetHighReg(int reg) { |
| 169 | DCHECK(IsPair()); |
| 170 | reg_ = (reg_ & ~kHighRegMask) | (reg << kHighRegShift); |
| 171 | DCHECK_EQ(GetHighReg(), reg); |
| 172 | } |
| 173 | |
buzbee | 2700f7e | 2014-03-07 09:46:20 -0800 | [diff] [blame^] | 174 | // Combine 2 32-bit solo regs into a pair. |
| 175 | static RegStorage MakeRegPair(RegStorage low, RegStorage high) { |
| 176 | DCHECK(!low.IsPair()); |
| 177 | DCHECK(low.Is32Bit()); |
| 178 | DCHECK(!high.IsPair()); |
| 179 | DCHECK(high.Is32Bit()); |
| 180 | return RegStorage(k64BitPair, low.GetReg(), high.GetReg()); |
| 181 | } |
| 182 | |
| 183 | // Create a 32-bit solo. |
| 184 | static RegStorage Solo32(int reg_num) { |
| 185 | return RegStorage(k32BitSolo, reg_num); |
| 186 | } |
| 187 | |
| 188 | // Create a 64-bit solo. |
| 189 | static RegStorage Solo64(int reg_num) { |
| 190 | return RegStorage(k64BitSolo, reg_num); |
| 191 | } |
| 192 | |
| 193 | static RegStorage InvalidReg() { |
| 194 | return RegStorage(kInvalid); |
| 195 | } |
| 196 | |
Bill Buzbee | 00e1ec6 | 2014-02-27 23:44:13 +0000 | [diff] [blame] | 197 | int GetRawBits() const { |
| 198 | return reg_; |
| 199 | } |
| 200 | |
| 201 | private: |
| 202 | uint16_t reg_; |
| 203 | }; |
| 204 | |
| 205 | } // namespace art |
| 206 | |
| 207 | #endif // ART_COMPILER_DEX_REG_STORAGE_H_ |