Chromium Code Reviews| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 // Spill slots. | 285 // Spill slots. |
| 286 static Location StackSlot(intptr_t stack_index) { | 286 static Location StackSlot(intptr_t stack_index, |
| 287 uword payload = EncodeStackIndex(stack_index); | 287 Register base = FPREG) { |
| 288 uword payload = StackSlotBaseField::encode(base) | |
| 289 | StackIndexField::encode(EncodeStackIndex(stack_index)); | |
| 288 Location loc(kStackSlot, payload); | 290 Location loc(kStackSlot, payload); |
| 289 // Ensure that sign is preserved. | 291 // Ensure that sign is preserved. |
| 290 ASSERT(loc.stack_index() == stack_index); | 292 ASSERT(loc.stack_index() == stack_index); |
| 291 return loc; | 293 return loc; |
| 292 } | 294 } |
| 293 | 295 |
| 294 bool IsStackSlot() const { | 296 bool IsStackSlot() const { |
| 295 return kind() == kStackSlot; | 297 return kind() == kStackSlot; |
| 296 } | 298 } |
| 297 | 299 |
| 298 static Location DoubleStackSlot(intptr_t stack_index) { | 300 static Location DoubleStackSlot(intptr_t stack_index) { |
| 299 uword payload = EncodeStackIndex(stack_index); | 301 uword payload = StackSlotBaseField::encode(FPREG) |
| 302 | StackIndexField::encode(EncodeStackIndex(stack_index)); | |
| 300 Location loc(kDoubleStackSlot, payload); | 303 Location loc(kDoubleStackSlot, payload); |
| 301 // Ensure that sign is preserved. | 304 // Ensure that sign is preserved. |
| 302 ASSERT(loc.stack_index() == stack_index); | 305 ASSERT(loc.stack_index() == stack_index); |
| 303 return loc; | 306 return loc; |
| 304 } | 307 } |
| 305 | 308 |
| 306 bool IsDoubleStackSlot() const { | 309 bool IsDoubleStackSlot() const { |
| 307 return kind() == kDoubleStackSlot; | 310 return kind() == kDoubleStackSlot; |
| 308 } | 311 } |
| 309 | 312 |
| 310 static Location QuadStackSlot(intptr_t stack_index) { | 313 static Location QuadStackSlot(intptr_t stack_index) { |
| 311 uword payload = EncodeStackIndex(stack_index); | 314 uword payload = StackSlotBaseField::encode(FPREG) |
| 315 | StackIndexField::encode(EncodeStackIndex(stack_index)); | |
| 312 Location loc(kQuadStackSlot, payload); | 316 Location loc(kQuadStackSlot, payload); |
| 313 // Ensure that sign is preserved. | 317 // Ensure that sign is preserved. |
| 314 ASSERT(loc.stack_index() == stack_index); | 318 ASSERT(loc.stack_index() == stack_index); |
| 315 return loc; | 319 return loc; |
| 316 } | 320 } |
| 317 | 321 |
| 318 bool IsQuadStackSlot() const { | 322 bool IsQuadStackSlot() const { |
| 319 return kind() == kQuadStackSlot; | 323 return kind() == kQuadStackSlot; |
| 320 } | 324 } |
| 321 | 325 |
| 326 Register base_reg() const { | |
| 327 ASSERT(HasStackIndex()); | |
| 328 return StackSlotBaseField::decode(payload()); | |
| 329 } | |
| 330 | |
| 322 intptr_t stack_index() const { | 331 intptr_t stack_index() const { |
| 323 ASSERT(HasStackIndex()); | 332 ASSERT(HasStackIndex()); |
| 324 // Decode stack index manually to preserve sign. | 333 // Decode stack index manually to preserve sign. |
| 325 return payload() - kStackIndexBias; | 334 return StackIndexField::decode(payload()) - kStackIndexBias; |
| 326 } | 335 } |
| 327 | 336 |
| 328 bool HasStackIndex() const { | 337 bool HasStackIndex() const { |
| 329 return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot(); | 338 return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot(); |
| 330 } | 339 } |
| 331 | 340 |
| 332 // Return a memory operand for stack slot locations. | 341 // Return a memory operand for stack slot locations. |
| 333 Address ToStackSlotAddress() const; | 342 Address ToStackSlotAddress() const; |
| 334 | 343 |
| 335 // Returns the offset from the frame pointer for stack slot locations. | 344 // 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_); | 380 return PayloadField::decode(value_); |
| 372 } | 381 } |
| 373 | 382 |
| 374 typedef BitField<Kind, 0, kBitsForKind> KindField; | 383 typedef BitField<Kind, 0, kBitsForKind> KindField; |
| 375 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 384 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
| 376 | 385 |
| 377 // Layout for kUnallocated locations payload. | 386 // Layout for kUnallocated locations payload. |
| 378 typedef BitField<Policy, 0, 3> PolicyField; | 387 typedef BitField<Policy, 0, 3> PolicyField; |
| 379 | 388 |
| 380 // Layout for stack slots. | 389 // Layout for stack slots. |
| 390 static const intptr_t kBitsForBaseReg = 5; | |
|
zra
2014/09/04 16:05:39
It looks like the base reg can only ever be FPREG
Florian Schneider
2014/09/04 16:17:24
It seems the most straight-forward to encode the r
| |
| 391 static const intptr_t kBitsForStackIndex = kBitsForPayload - kBitsForBaseReg; | |
| 392 typedef BitField<Register, 0, kBitsForBaseReg> StackSlotBaseField; | |
| 393 typedef BitField<intptr_t, | |
| 394 kBitsForBaseReg, | |
| 395 kBitsForStackIndex> StackIndexField; | |
| 396 COMPILE_ASSERT(1 << kBitsForBaseReg >= kNumberOfCpuRegisters); | |
| 397 | |
| 381 static const intptr_t kStackIndexBias = | 398 static const intptr_t kStackIndexBias = |
| 382 static_cast<intptr_t>(1) << (kBitsForPayload - 1); | 399 static_cast<intptr_t>(1) << (kBitsForStackIndex - 1); |
| 383 | 400 |
| 384 // Location either contains kind and payload fields or a tagged handle for | 401 // 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 | 402 // 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. | 403 // way that none of them can be interpreted as a kConstant tag. |
| 387 uword value_; | 404 uword value_; |
| 388 }; | 405 }; |
| 389 | 406 |
| 390 | 407 |
| 391 class PairLocation : public ZoneAllocated { | 408 class PairLocation : public ZoneAllocated { |
| 392 public: | 409 public: |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 | 669 |
| 653 #if defined(DEBUG) | 670 #if defined(DEBUG) |
| 654 intptr_t writable_inputs_; | 671 intptr_t writable_inputs_; |
| 655 #endif | 672 #endif |
| 656 }; | 673 }; |
| 657 | 674 |
| 658 | 675 |
| 659 } // namespace dart | 676 } // namespace dart |
| 660 | 677 |
| 661 #endif // VM_LOCATIONS_H_ | 678 #endif // VM_LOCATIONS_H_ |
| OLD | NEW |