| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_LOCATIONS_H_ | 5 #ifndef VM_LOCATIONS_H_ |
| 6 #define VM_LOCATIONS_H_ | 6 #define VM_LOCATIONS_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bitfield.h" | 10 #include "vm/bitfield.h" |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 ASSERT(IsMachineRegister()); | 275 ASSERT(IsMachineRegister()); |
| 276 return static_cast<intptr_t>(payload()); | 276 return static_cast<intptr_t>(payload()); |
| 277 } | 277 } |
| 278 | 278 |
| 279 static uword EncodeStackIndex(intptr_t stack_index) { | 279 static uword EncodeStackIndex(intptr_t stack_index) { |
| 280 ASSERT((-kStackIndexBias <= stack_index) && | 280 ASSERT((-kStackIndexBias <= stack_index) && |
| 281 (stack_index < kStackIndexBias)); | 281 (stack_index < kStackIndexBias)); |
| 282 return static_cast<uword>(kStackIndexBias + stack_index); | 282 return static_cast<uword>(kStackIndexBias + stack_index); |
| 283 } | 283 } |
| 284 | 284 |
| 285 enum StackSlotBase { |
| 286 kFpRelative, |
| 287 kSpRelative |
| 288 }; |
| 289 |
| 285 // Spill slots. | 290 // Spill slots. |
| 286 static Location StackSlot(intptr_t stack_index) { | 291 static Location StackSlot(intptr_t stack_index, |
| 287 uword payload = EncodeStackIndex(stack_index); | 292 Register base = FPREG) { |
| 293 uword payload = StackSlotBaseField::encode(base) |
| 294 | StackIndexField::encode(EncodeStackIndex(stack_index)); |
| 288 Location loc(kStackSlot, payload); | 295 Location loc(kStackSlot, payload); |
| 289 // Ensure that sign is preserved. | 296 // Ensure that sign is preserved. |
| 290 ASSERT(loc.stack_index() == stack_index); | 297 ASSERT(loc.stack_index() == stack_index); |
| 291 return loc; | 298 return loc; |
| 292 } | 299 } |
| 293 | 300 |
| 294 bool IsStackSlot() const { | 301 bool IsStackSlot() const { |
| 295 return kind() == kStackSlot; | 302 return kind() == kStackSlot; |
| 296 } | 303 } |
| 297 | 304 |
| 298 static Location DoubleStackSlot(intptr_t stack_index) { | 305 static Location DoubleStackSlot(intptr_t stack_index) { |
| 299 uword payload = EncodeStackIndex(stack_index); | 306 uword payload = StackSlotBaseField::encode(FPREG) |
| 307 | StackIndexField::encode(EncodeStackIndex(stack_index)); |
| 300 Location loc(kDoubleStackSlot, payload); | 308 Location loc(kDoubleStackSlot, payload); |
| 301 // Ensure that sign is preserved. | 309 // Ensure that sign is preserved. |
| 302 ASSERT(loc.stack_index() == stack_index); | 310 ASSERT(loc.stack_index() == stack_index); |
| 303 return loc; | 311 return loc; |
| 304 } | 312 } |
| 305 | 313 |
| 306 bool IsDoubleStackSlot() const { | 314 bool IsDoubleStackSlot() const { |
| 307 return kind() == kDoubleStackSlot; | 315 return kind() == kDoubleStackSlot; |
| 308 } | 316 } |
| 309 | 317 |
| 310 static Location QuadStackSlot(intptr_t stack_index) { | 318 static Location QuadStackSlot(intptr_t stack_index) { |
| 311 uword payload = EncodeStackIndex(stack_index); | 319 uword payload = StackSlotBaseField::encode(FPREG) |
| 320 | StackIndexField::encode(EncodeStackIndex(stack_index)); |
| 312 Location loc(kQuadStackSlot, payload); | 321 Location loc(kQuadStackSlot, payload); |
| 313 // Ensure that sign is preserved. | 322 // Ensure that sign is preserved. |
| 314 ASSERT(loc.stack_index() == stack_index); | 323 ASSERT(loc.stack_index() == stack_index); |
| 315 return loc; | 324 return loc; |
| 316 } | 325 } |
| 317 | 326 |
| 318 bool IsQuadStackSlot() const { | 327 bool IsQuadStackSlot() const { |
| 319 return kind() == kQuadStackSlot; | 328 return kind() == kQuadStackSlot; |
| 320 } | 329 } |
| 321 | 330 |
| 331 Register base_reg() const { |
| 332 ASSERT(HasStackIndex()); |
| 333 return StackSlotBaseField::decode(payload()); |
| 334 } |
| 335 |
| 322 intptr_t stack_index() const { | 336 intptr_t stack_index() const { |
| 323 ASSERT(HasStackIndex()); | 337 ASSERT(HasStackIndex()); |
| 324 // Decode stack index manually to preserve sign. | 338 // Decode stack index manually to preserve sign. |
| 325 return payload() - kStackIndexBias; | 339 return StackIndexField::decode(payload()) - kStackIndexBias; |
| 326 } | 340 } |
| 327 | 341 |
| 328 bool HasStackIndex() const { | 342 bool HasStackIndex() const { |
| 329 return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot(); | 343 return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot(); |
| 330 } | 344 } |
| 331 | 345 |
| 332 // Return a memory operand for stack slot locations. | 346 // Return a memory operand for stack slot locations. |
| 333 Address ToStackSlotAddress() const; | 347 Address ToStackSlotAddress() const; |
| 334 | 348 |
| 335 // Returns the offset from the frame pointer for stack slot locations. | 349 // Returns the offset from the frame pointer for stack slot locations. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 return PayloadField::decode(value_); | 385 return PayloadField::decode(value_); |
| 372 } | 386 } |
| 373 | 387 |
| 374 typedef BitField<Kind, 0, kBitsForKind> KindField; | 388 typedef BitField<Kind, 0, kBitsForKind> KindField; |
| 375 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 389 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
| 376 | 390 |
| 377 // Layout for kUnallocated locations payload. | 391 // Layout for kUnallocated locations payload. |
| 378 typedef BitField<Policy, 0, 3> PolicyField; | 392 typedef BitField<Policy, 0, 3> PolicyField; |
| 379 | 393 |
| 380 // Layout for stack slots. | 394 // Layout for stack slots. |
| 395 static const intptr_t kBitsForBaseReg = 5; |
| 396 static const intptr_t kBitsForStackIndex = kBitsForPayload - kBitsForBaseReg; |
| 397 typedef BitField<Register, 0, kBitsForBaseReg> StackSlotBaseField; |
| 398 typedef BitField<intptr_t, |
| 399 kBitsForBaseReg, |
| 400 kBitsForStackIndex> StackIndexField; |
| 401 COMPILE_ASSERT(1 << kBitsForBaseReg >= kNumberOfCpuRegisters); |
| 402 |
| 381 static const intptr_t kStackIndexBias = | 403 static const intptr_t kStackIndexBias = |
| 382 static_cast<intptr_t>(1) << (kBitsForPayload - 1); | 404 static_cast<intptr_t>(1) << (kBitsForStackIndex - 1); |
| 383 | 405 |
| 384 // Location either contains kind and payload fields or a tagged handle for | 406 // Location either contains kind and payload fields or a tagged handle for |
| 385 // a constant locations. Values of enumeration Kind are selected in such a | 407 // a constant locations. Values of enumeration Kind are selected in such a |
| 386 // way that none of them can be interpreted as a kConstant tag. | 408 // way that none of them can be interpreted as a kConstant tag. |
| 387 uword value_; | 409 uword value_; |
| 388 }; | 410 }; |
| 389 | 411 |
| 390 | 412 |
| 391 class PairLocation : public ZoneAllocated { | 413 class PairLocation : public ZoneAllocated { |
| 392 public: | 414 public: |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 BitmapBuilder* stack_bitmap_; | 663 BitmapBuilder* stack_bitmap_; |
| 642 | 664 |
| 643 const ContainsCall contains_call_; | 665 const ContainsCall contains_call_; |
| 644 RegisterSet live_registers_; | 666 RegisterSet live_registers_; |
| 645 }; | 667 }; |
| 646 | 668 |
| 647 | 669 |
| 648 } // namespace dart | 670 } // namespace dart |
| 649 | 671 |
| 650 #endif // VM_LOCATIONS_H_ | 672 #endif // VM_LOCATIONS_H_ |
| OLD | NEW |