| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ | 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ |
| 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ | 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ |
| 7 | 7 |
| 8 #include <list> | 8 #include <list> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 // These memebers are necessary for compilation. | 128 // These memebers are necessary for compilation. |
| 129 // A few of them may be unused for now. | 129 // A few of them may be unused for now. |
| 130 | 130 |
| 131 static const int kNumRegisters = kNumberOfRegisters; | 131 static const int kNumRegisters = kNumberOfRegisters; |
| 132 static int NumRegisters() { return kNumRegisters; } | 132 static int NumRegisters() { return kNumRegisters; } |
| 133 | 133 |
| 134 // We allow crankshaft to use the following registers: | 134 // We allow crankshaft to use the following registers: |
| 135 // - x0 to x15 | 135 // - x0 to x15 |
| 136 // - x18 to x24 | 136 // - x18 to x24 |
| 137 // - x27 (also context) | 137 // - x27 (also context) |
| 138 // - x30 (also lr) |
| 138 // | 139 // |
| 139 // TODO(all): Register x25 is currently free and could be available for | 140 // TODO(all): Register x25 is currently free and could be available for |
| 140 // crankshaft, but we don't use it as we might use it as a per function | 141 // crankshaft, but we don't use it as we might use it as a per function |
| 141 // literal pool pointer in the future. | 142 // literal pool pointer in the future. |
| 142 // | 143 // |
| 143 // TODO(all): Consider storing cp in x25 to have only two ranges. | 144 // TODO(all): Consider storing cp in x25 to have only two ranges. |
| 144 // We split allocatable registers in three ranges called | 145 // We split allocatable registers in three ranges called |
| 145 // - "low range" | 146 // - "low range" |
| 146 // - "high range" | 147 // - "high range" |
| 147 // - "context" | 148 // - "context" |
| 148 static const unsigned kAllocatableLowRangeBegin = 0; | 149 static const unsigned kAllocatableLowRangeBegin = 0; |
| 149 static const unsigned kAllocatableLowRangeEnd = 15; | 150 static const unsigned kAllocatableLowRangeEnd = 15; |
| 150 static const unsigned kAllocatableHighRangeBegin = 18; | 151 static const unsigned kAllocatableHighRangeBegin = 18; |
| 151 static const unsigned kAllocatableHighRangeEnd = 24; | 152 static const unsigned kAllocatableHighRangeEnd = 24; |
| 152 static const unsigned kAllocatableContext = 27; | 153 static const unsigned kAllocatableContext = 27; |
| 154 static const unsigned kAllocatableLR = 30; |
| 155 |
| 156 static const RegList kAllocatableRegisters = |
| 157 ((1 << (kAllocatableLowRangeEnd + 1)) - |
| 158 (1 << kAllocatableLowRangeBegin)) | |
| 159 ((1 << (kAllocatableHighRangeEnd + 1)) - |
| 160 (1 << kAllocatableHighRangeBegin)) | |
| 161 (1 << kAllocatableLR) | (1 << kAllocatableContext); |
| 153 | 162 |
| 154 // Gap between low and high ranges. | 163 // Gap between low and high ranges. |
| 155 static const int kAllocatableRangeGapSize = | 164 static const int kAllocatableRangeGapSize = |
| 156 (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; | 165 (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; |
| 157 | 166 |
| 158 static const int kMaxNumAllocatableRegisters = | 167 static const int kMaxNumAllocatableRegisters = |
| 159 (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + | 168 (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + |
| 160 (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1) + 1; // cp | 169 (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1) + 2; // cp/lr |
| 161 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | 170 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
| 162 | 171 |
| 163 // Return true if the register is one that crankshaft can allocate. | 172 // Return true if the register is one that crankshaft can allocate. |
| 164 bool IsAllocatable() const { | 173 bool IsAllocatable() const { |
| 165 return ((reg_code == kAllocatableContext) || | 174 return ((reg_code == kAllocatableContext) || |
| 175 (reg_code == kAllocatableLR) || |
| 166 (reg_code <= kAllocatableLowRangeEnd) || | 176 (reg_code <= kAllocatableLowRangeEnd) || |
| 167 ((reg_code >= kAllocatableHighRangeBegin) && | 177 ((reg_code >= kAllocatableHighRangeBegin) && |
| 168 (reg_code <= kAllocatableHighRangeEnd))); | 178 (reg_code <= kAllocatableHighRangeEnd))); |
| 169 } | 179 } |
| 170 | 180 |
| 171 static Register FromAllocationIndex(unsigned index) { | 181 static Register FromAllocationIndex(unsigned index) { |
| 172 ASSERT(index < static_cast<unsigned>(NumAllocatableRegisters())); | 182 ASSERT(index < static_cast<unsigned>(NumAllocatableRegisters())); |
| 173 // cp is the last allocatable register. | 183 // lr is the last allocatable register. |
| 174 if (index == (static_cast<unsigned>(NumAllocatableRegisters() - 1))) { | 184 if (index == (static_cast<unsigned>(NumAllocatableRegisters() - 1))) { |
| 185 return from_code(kAllocatableLR); |
| 186 } |
| 187 // cp is the second-last allocatable register. |
| 188 if (index == (static_cast<unsigned>(NumAllocatableRegisters() - 2))) { |
| 175 return from_code(kAllocatableContext); | 189 return from_code(kAllocatableContext); |
| 176 } | 190 } |
| 177 | 191 |
| 178 // Handle low and high ranges. | 192 // Handle low and high ranges. |
| 179 return (index <= kAllocatableLowRangeEnd) | 193 return (index <= kAllocatableLowRangeEnd) |
| 180 ? from_code(index) | 194 ? from_code(index) |
| 181 : from_code(index + kAllocatableRangeGapSize); | 195 : from_code(index + kAllocatableRangeGapSize); |
| 182 } | 196 } |
| 183 | 197 |
| 184 static const char* AllocationIndexToString(int index) { | 198 static const char* AllocationIndexToString(int index) { |
| 185 ASSERT((index >= 0) && (index < NumAllocatableRegisters())); | 199 ASSERT((index >= 0) && (index < NumAllocatableRegisters())); |
| 186 ASSERT((kAllocatableLowRangeBegin == 0) && | 200 STATIC_ASSERT((kAllocatableLowRangeBegin == 0) && |
| 187 (kAllocatableLowRangeEnd == 15) && | 201 (kAllocatableLowRangeEnd == 15) && |
| 188 (kAllocatableHighRangeBegin == 18) && | 202 (kAllocatableHighRangeBegin == 18) && |
| 189 (kAllocatableHighRangeEnd == 24) && | 203 (kAllocatableHighRangeEnd == 24) && |
| 190 (kAllocatableContext == 27)); | 204 (kAllocatableContext == 27) && |
| 205 (kAllocatableLR == 30)); |
| 191 const char* const names[] = { | 206 const char* const names[] = { |
| 192 "x0", "x1", "x2", "x3", "x4", | 207 "x0", "x1", "x2", "x3", "x4", |
| 193 "x5", "x6", "x7", "x8", "x9", | 208 "x5", "x6", "x7", "x8", "x9", |
| 194 "x10", "x11", "x12", "x13", "x14", | 209 "x10", "x11", "x12", "x13", "x14", |
| 195 "x15", "x18", "x19", "x20", "x21", | 210 "x15", "x18", "x19", "x20", "x21", |
| 196 "x22", "x23", "x24", "x27", | 211 "x22", "x23", "x24", "x27", "lr" |
| 197 }; | 212 }; |
| 198 return names[index]; | 213 return names[index]; |
| 199 } | 214 } |
| 200 | 215 |
| 201 static int ToAllocationIndex(Register reg) { | 216 static int ToAllocationIndex(Register reg) { |
| 202 ASSERT(reg.IsAllocatable()); | 217 ASSERT(reg.IsAllocatable()); |
| 203 unsigned code = reg.code(); | 218 unsigned code = reg.code(); |
| 219 if (code == kAllocatableLR) { |
| 220 return NumAllocatableRegisters() - 1; |
| 221 } |
| 204 if (code == kAllocatableContext) { | 222 if (code == kAllocatableContext) { |
| 205 return NumAllocatableRegisters() - 1; | 223 return NumAllocatableRegisters() - 2; |
| 206 } | 224 } |
| 207 | 225 |
| 208 return (code <= kAllocatableLowRangeEnd) | 226 return (code <= kAllocatableLowRangeEnd) |
| 209 ? code | 227 ? code |
| 210 : code - kAllocatableRangeGapSize; | 228 : code - kAllocatableRangeGapSize; |
| 211 } | 229 } |
| 212 | 230 |
| 213 static Register from_code(int code) { | 231 static Register from_code(int code) { |
| 214 // Always return an X register. | 232 // Always return an X register. |
| 215 return Register::Create(code, kXRegSizeInBits); | 233 return Register::Create(code, kXRegSizeInBits); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 | 276 |
| 259 // Crankshaft can use all the FP registers except: | 277 // Crankshaft can use all the FP registers except: |
| 260 // - d15 which is used to keep the 0 double value | 278 // - d15 which is used to keep the 0 double value |
| 261 // - d30 which is used in crankshaft as a double scratch register | 279 // - d30 which is used in crankshaft as a double scratch register |
| 262 // - d31 which is used in the MacroAssembler as a double scratch register | 280 // - d31 which is used in the MacroAssembler as a double scratch register |
| 263 static const unsigned kAllocatableLowRangeBegin = 0; | 281 static const unsigned kAllocatableLowRangeBegin = 0; |
| 264 static const unsigned kAllocatableLowRangeEnd = 14; | 282 static const unsigned kAllocatableLowRangeEnd = 14; |
| 265 static const unsigned kAllocatableHighRangeBegin = 16; | 283 static const unsigned kAllocatableHighRangeBegin = 16; |
| 266 static const unsigned kAllocatableHighRangeEnd = 28; | 284 static const unsigned kAllocatableHighRangeEnd = 28; |
| 267 | 285 |
| 268 static const RegList kAllocatableFPRegisters = 0x1fff7fff; | 286 static const RegList kAllocatableFPRegisters = |
| 287 ((1 << (kAllocatableLowRangeEnd + 1)) - |
| 288 (1 << kAllocatableLowRangeBegin)) | |
| 289 ((1 << (kAllocatableHighRangeEnd + 1)) - |
| 290 (1 << kAllocatableHighRangeBegin)); |
| 269 | 291 |
| 270 // Gap between low and high ranges. | 292 // Gap between low and high ranges. |
| 271 static const int kAllocatableRangeGapSize = | 293 static const int kAllocatableRangeGapSize = |
| 272 (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; | 294 (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; |
| 273 | 295 |
| 274 static const int kMaxNumAllocatableRegisters = | 296 static const int kMaxNumAllocatableRegisters = |
| 275 (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + | 297 (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + |
| 276 (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1); | 298 (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1); |
| 277 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | 299 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
| 278 | 300 |
| (...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2247 class EnsureSpace BASE_EMBEDDED { | 2269 class EnsureSpace BASE_EMBEDDED { |
| 2248 public: | 2270 public: |
| 2249 explicit EnsureSpace(Assembler* assembler) { | 2271 explicit EnsureSpace(Assembler* assembler) { |
| 2250 assembler->CheckBufferSpace(); | 2272 assembler->CheckBufferSpace(); |
| 2251 } | 2273 } |
| 2252 }; | 2274 }; |
| 2253 | 2275 |
| 2254 } } // namespace v8::internal | 2276 } } // namespace v8::internal |
| 2255 | 2277 |
| 2256 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ | 2278 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ |
| OLD | NEW |