| OLD | NEW |
| 1 // Copyright (c) 2012, 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" |
| 11 | 11 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 // Spill slot allocated by the register allocator. Payload contains | 57 // Spill slot allocated by the register allocator. Payload contains |
| 58 // a spill index. | 58 // a spill index. |
| 59 kStackSlot = 3, | 59 kStackSlot = 3, |
| 60 kDoubleStackSlot = 4, | 60 kDoubleStackSlot = 4, |
| 61 | 61 |
| 62 // Register location represents a fixed register. Payload contains | 62 // Register location represents a fixed register. Payload contains |
| 63 // register code. | 63 // register code. |
| 64 kRegister = 6, | 64 kRegister = 6, |
| 65 | 65 |
| 66 // XmmRegister location represents a fixed xmm register. Payload contains | 66 // FpuRegister location represents a fixed fpu register. Payload contains |
| 67 // its code. | 67 // its code. |
| 68 kXmmRegister = 7, | 68 kFpuRegister = 7, |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 Location() : value_(kInvalidLocation) { | 71 Location() : value_(kInvalidLocation) { |
| 72 ASSERT(IsInvalid()); | 72 ASSERT(IsInvalid()); |
| 73 } | 73 } |
| 74 | 74 |
| 75 Location(const Location& other) : ValueObject(), value_(other.value_) { } |
| 76 |
| 77 Location& operator=(const Location& other) { |
| 78 value_ = other.value_; |
| 79 return *this; |
| 80 } |
| 81 |
| 75 bool IsInvalid() const { | 82 bool IsInvalid() const { |
| 76 return value_ == kInvalidLocation; | 83 return value_ == kInvalidLocation; |
| 77 } | 84 } |
| 78 | 85 |
| 79 // Constants. | 86 // Constants. |
| 80 bool IsConstant() const { | 87 bool IsConstant() const { |
| 81 ASSERT((kConstant & kConstantMask) == kConstant); | 88 ASSERT((kConstant & kConstantMask) == kConstant); |
| 82 return (value_ & kConstantMask) == kConstant; | 89 return (value_ & kConstantMask) == kConstant; |
| 83 } | 90 } |
| 84 | 91 |
| 85 static Location Constant(const Object& obj) { | 92 static Location Constant(const Object& obj) { |
| 86 Location loc(reinterpret_cast<uword>(&obj) | kConstant); | 93 Location loc(reinterpret_cast<uword>(&obj) | kConstant); |
| 87 ASSERT(&obj == &loc.constant()); | 94 ASSERT(&obj == &loc.constant()); |
| 88 return loc; | 95 return loc; |
| 89 } | 96 } |
| 90 | 97 |
| 91 const Object& constant() const { | 98 const Object& constant() const { |
| 92 ASSERT(IsConstant()); | 99 ASSERT(IsConstant()); |
| 93 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask); | 100 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask); |
| 94 } | 101 } |
| 95 | 102 |
| 96 // Unallocated locations. | 103 // Unallocated locations. |
| 97 enum Policy { | 104 enum Policy { |
| 98 kAny, | 105 kAny, |
| 99 kPrefersRegister, | 106 kPrefersRegister, |
| 100 kRequiresRegister, | 107 kRequiresRegister, |
| 101 kRequiresXmmRegister, | 108 kRequiresFpuRegister, |
| 102 kWritableRegister, | 109 kWritableRegister, |
| 103 kSameAsFirstInput, | 110 kSameAsFirstInput, |
| 104 }; | 111 }; |
| 105 | 112 |
| 106 bool IsUnallocated() const { | 113 bool IsUnallocated() const { |
| 107 return kind() == kUnallocated; | 114 return kind() == kUnallocated; |
| 108 } | 115 } |
| 109 | 116 |
| 110 bool IsRegisterBeneficial() { | 117 bool IsRegisterBeneficial() { |
| 111 return !Equals(Any()); | 118 return !Equals(Any()); |
| 112 } | 119 } |
| 113 | 120 |
| 114 static Location UnallocatedLocation(Policy policy) { | 121 static Location UnallocatedLocation(Policy policy) { |
| 115 return Location(kUnallocated, PolicyField::encode(policy)); | 122 return Location(kUnallocated, PolicyField::encode(policy)); |
| 116 } | 123 } |
| 117 | 124 |
| 118 // Any free register is suitable to replace this unallocated location. | 125 // Any free register is suitable to replace this unallocated location. |
| 119 static Location Any() { | 126 static Location Any() { |
| 120 return UnallocatedLocation(kAny); | 127 return UnallocatedLocation(kAny); |
| 121 } | 128 } |
| 122 | 129 |
| 123 static Location PrefersRegister() { | 130 static Location PrefersRegister() { |
| 124 return UnallocatedLocation(kPrefersRegister); | 131 return UnallocatedLocation(kPrefersRegister); |
| 125 } | 132 } |
| 126 | 133 |
| 127 static Location RequiresRegister() { | 134 static Location RequiresRegister() { |
| 128 return UnallocatedLocation(kRequiresRegister); | 135 return UnallocatedLocation(kRequiresRegister); |
| 129 } | 136 } |
| 130 | 137 |
| 131 static Location RequiresXmmRegister() { | 138 static Location RequiresFpuRegister() { |
| 132 return UnallocatedLocation(kRequiresXmmRegister); | 139 return UnallocatedLocation(kRequiresFpuRegister); |
| 133 } | 140 } |
| 134 | 141 |
| 135 static Location WritableRegister() { | 142 static Location WritableRegister() { |
| 136 return UnallocatedLocation(kWritableRegister); | 143 return UnallocatedLocation(kWritableRegister); |
| 137 } | 144 } |
| 138 | 145 |
| 139 // The location of the first input to the instruction will be | 146 // The location of the first input to the instruction will be |
| 140 // used to replace this unallocated location. | 147 // used to replace this unallocated location. |
| 141 static Location SameAsFirstInput() { | 148 static Location SameAsFirstInput() { |
| 142 return UnallocatedLocation(kSameAsFirstInput); | 149 return UnallocatedLocation(kSameAsFirstInput); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 162 | 169 |
| 163 bool IsRegister() const { | 170 bool IsRegister() const { |
| 164 return kind() == kRegister; | 171 return kind() == kRegister; |
| 165 } | 172 } |
| 166 | 173 |
| 167 Register reg() const { | 174 Register reg() const { |
| 168 ASSERT(IsRegister()); | 175 ASSERT(IsRegister()); |
| 169 return RegisterField::decode(payload()); | 176 return RegisterField::decode(payload()); |
| 170 } | 177 } |
| 171 | 178 |
| 172 // XMM registers and double spill slots can contain either doubles | 179 // FPU registers and double spill slots can contain either doubles |
| 173 // or 64-bit integers. | 180 // or 64-bit integers. |
| 174 enum Representation { | 181 enum Representation { |
| 175 kDouble, | 182 kDouble, |
| 176 kMint | 183 kMint |
| 177 }; | 184 }; |
| 178 | 185 |
| 179 Representation representation() const { | 186 Representation representation() const { |
| 180 ASSERT(IsXmmRegister() || IsDoubleStackSlot()); | 187 ASSERT(IsFpuRegister() || IsDoubleStackSlot()); |
| 181 return RepresentationField::decode(payload()); | 188 return RepresentationField::decode(payload()); |
| 182 } | 189 } |
| 183 | 190 |
| 184 // XmmRegister locations. | 191 // FpuRegister locations. |
| 185 static Location XmmRegisterLocation(XmmRegister reg, Representation rep) { | 192 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { |
| 186 uword payload = | 193 uword payload = |
| 187 XmmRegisterField::encode(reg) | RepresentationField::encode(rep); | 194 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); |
| 188 return Location(kXmmRegister, payload); | 195 return Location(kFpuRegister, payload); |
| 189 } | 196 } |
| 190 | 197 |
| 191 bool IsXmmRegister() const { | 198 bool IsFpuRegister() const { |
| 192 return kind() == kXmmRegister; | 199 return kind() == kFpuRegister; |
| 193 } | 200 } |
| 194 | 201 |
| 195 XmmRegister xmm_reg() const { | 202 FpuRegister fpu_reg() const { |
| 196 ASSERT(IsXmmRegister()); | 203 ASSERT(IsFpuRegister()); |
| 197 return XmmRegisterField::decode(payload()); | 204 return FpuRegisterField::decode(payload()); |
| 198 } | 205 } |
| 199 | 206 |
| 200 static bool IsMachineRegisterKind(Kind kind) { | 207 static bool IsMachineRegisterKind(Kind kind) { |
| 201 return (kind & kMachineRegisterMask) == kMachineRegister; | 208 return (kind & kMachineRegisterMask) == kMachineRegister; |
| 202 } | 209 } |
| 203 | 210 |
| 204 static Location MachineRegisterLocation(Kind kind, | 211 static Location MachineRegisterLocation(Kind kind, |
| 205 intptr_t reg, | 212 intptr_t reg, |
| 206 Representation rep) { | 213 Representation rep) { |
| 207 if (kind == kRegister) { | 214 if (kind == kRegister) { |
| 208 return RegisterLocation(static_cast<Register>(reg)); | 215 return RegisterLocation(static_cast<Register>(reg)); |
| 209 } else { | 216 } else { |
| 210 ASSERT(kind == kXmmRegister); | 217 ASSERT(kind == kFpuRegister); |
| 211 return XmmRegisterLocation(static_cast<XmmRegister>(reg), rep); | 218 return FpuRegisterLocation(static_cast<FpuRegister>(reg), rep); |
| 212 } | 219 } |
| 213 } | 220 } |
| 214 | 221 |
| 215 bool IsMachineRegister() const { | 222 bool IsMachineRegister() const { |
| 216 return IsMachineRegisterKind(kind()); | 223 return IsMachineRegisterKind(kind()); |
| 217 } | 224 } |
| 218 | 225 |
| 219 intptr_t register_code() const { | 226 intptr_t register_code() const { |
| 220 ASSERT(IsMachineRegister()); | 227 ASSERT(IsMachineRegister()); |
| 221 return static_cast<intptr_t>(RegisterField::decode(payload())); | 228 return static_cast<intptr_t>(RegisterField::decode(payload())); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 return PayloadField::decode(value_); | 304 return PayloadField::decode(value_); |
| 298 } | 305 } |
| 299 | 306 |
| 300 typedef BitField<Kind, 0, kBitsForKind> KindField; | 307 typedef BitField<Kind, 0, kBitsForKind> KindField; |
| 301 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 308 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
| 302 | 309 |
| 303 // Layout for kUnallocated locations payload. | 310 // Layout for kUnallocated locations payload. |
| 304 typedef BitField<Policy, 0, 3> PolicyField; | 311 typedef BitField<Policy, 0, 3> PolicyField; |
| 305 | 312 |
| 306 // Layout for register locations payload. The representation bit is only used | 313 // Layout for register locations payload. The representation bit is only used |
| 307 // for XmmRegister and unused for Register. | 314 // for FpuRegister and unused for Register. |
| 308 static const intptr_t kBitsForRepresentation = 1; | 315 static const intptr_t kBitsForRepresentation = 1; |
| 309 static const intptr_t kBitsForRegister = | 316 static const intptr_t kBitsForRegister = |
| 310 kBitsForPayload - kBitsForRepresentation; | 317 kBitsForPayload - kBitsForRepresentation; |
| 311 typedef BitField<Representation, | 318 typedef BitField<Representation, |
| 312 0, | 319 0, |
| 313 kBitsForRepresentation> RepresentationField; | 320 kBitsForRepresentation> RepresentationField; |
| 314 typedef BitField<Register, | 321 typedef BitField<Register, |
| 315 kBitsForRepresentation, | 322 kBitsForRepresentation, |
| 316 kBitsForRegister> RegisterField; | 323 kBitsForRegister> RegisterField; |
| 317 typedef BitField<XmmRegister, | 324 typedef BitField<FpuRegister, |
| 318 kBitsForRepresentation, | 325 kBitsForRepresentation, |
| 319 kBitsForRegister> XmmRegisterField; | 326 kBitsForRegister> FpuRegisterField; |
| 320 | 327 |
| 321 // Layout for stack slots. The representation bit is only used for | 328 // Layout for stack slots. The representation bit is only used for |
| 322 // DoubleStackSlot and unused for StackSlot. | 329 // DoubleStackSlot and unused for StackSlot. |
| 323 static const intptr_t kBitsForIndex = | 330 static const intptr_t kBitsForIndex = |
| 324 kBitsForPayload - kBitsForRepresentation; | 331 kBitsForPayload - kBitsForRepresentation; |
| 325 typedef BitField<uword, | 332 typedef BitField<uword, |
| 326 kBitsForRepresentation, | 333 kBitsForRepresentation, |
| 327 kBitsForIndex> IndexField; | 334 kBitsForIndex> IndexField; |
| 328 static const intptr_t kStackIndexBias = | 335 static const intptr_t kStackIndexBias = |
| 329 static_cast<intptr_t>(1) << (kBitsForIndex - 1); | 336 static_cast<intptr_t>(1) << (kBitsForIndex - 1); |
| 330 | 337 |
| 331 // Location either contains kind and payload fields or a tagged handle for | 338 // Location either contains kind and payload fields or a tagged handle for |
| 332 // a constant locations. Values of enumeration Kind are selected in such a | 339 // a constant locations. Values of enumeration Kind are selected in such a |
| 333 // way that none of them can be interpreted as a kConstant tag. | 340 // way that none of them can be interpreted as a kConstant tag. |
| 334 uword value_; | 341 uword value_; |
| 335 }; | 342 }; |
| 336 | 343 |
| 337 | 344 |
| 338 class RegisterSet : public ValueObject { | 345 class RegisterSet : public ValueObject { |
| 339 public: | 346 public: |
| 340 RegisterSet() : cpu_registers_(0), xmm_registers_(0) { | 347 RegisterSet() : cpu_registers_(0), fpu_registers_(0) { |
| 341 ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte)); | 348 ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte)); |
| 342 ASSERT(kNumberOfXmmRegisters < (kWordSize * kBitsPerByte)); | 349 ASSERT(kNumberOfFpuRegisters < (kWordSize * kBitsPerByte)); |
| 343 } | 350 } |
| 344 | 351 |
| 345 | 352 |
| 346 void Add(Location loc) { | 353 void Add(Location loc) { |
| 347 if (loc.IsRegister()) { | 354 if (loc.IsRegister()) { |
| 348 cpu_registers_ |= (1 << loc.reg()); | 355 cpu_registers_ |= (1 << loc.reg()); |
| 349 } else if (loc.IsXmmRegister()) { | 356 } else if (loc.IsFpuRegister()) { |
| 350 xmm_registers_ |= (1 << loc.xmm_reg()); | 357 fpu_registers_ |= (1 << loc.fpu_reg()); |
| 351 } | 358 } |
| 352 } | 359 } |
| 353 | 360 |
| 354 void Remove(Location loc) { | 361 void Remove(Location loc) { |
| 355 if (loc.IsRegister()) { | 362 if (loc.IsRegister()) { |
| 356 cpu_registers_ &= ~(1 << loc.reg()); | 363 cpu_registers_ &= ~(1 << loc.reg()); |
| 357 } else if (loc.IsXmmRegister()) { | 364 } else if (loc.IsFpuRegister()) { |
| 358 xmm_registers_ &= ~(1 << loc.xmm_reg()); | 365 fpu_registers_ &= ~(1 << loc.fpu_reg()); |
| 359 } | 366 } |
| 360 } | 367 } |
| 361 | 368 |
| 362 bool ContainsRegister(Register reg) { | 369 bool ContainsRegister(Register reg) { |
| 363 return (cpu_registers_ & (1 << reg)) != 0; | 370 return (cpu_registers_ & (1 << reg)) != 0; |
| 364 } | 371 } |
| 365 | 372 |
| 366 bool ContainsXmmRegister(XmmRegister xmm_reg) { | 373 bool ContainsFpuRegister(FpuRegister fpu_reg) { |
| 367 return (xmm_registers_ & (1 << xmm_reg)) != 0; | 374 return (fpu_registers_ & (1 << fpu_reg)) != 0; |
| 368 } | 375 } |
| 369 | 376 |
| 370 intptr_t xmm_regs_count() { | 377 intptr_t fpu_regs_count() { |
| 371 intptr_t count = 0; | 378 intptr_t count = 0; |
| 372 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; reg_idx++) { | 379 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; reg_idx++) { |
| 373 if (ContainsXmmRegister(static_cast<XmmRegister>(reg_idx))) { | 380 if (ContainsFpuRegister(static_cast<FpuRegister>(reg_idx))) { |
| 374 count++; | 381 count++; |
| 375 } | 382 } |
| 376 } | 383 } |
| 377 return count; | 384 return count; |
| 378 } | 385 } |
| 379 | 386 |
| 380 private: | 387 private: |
| 381 intptr_t cpu_registers_; | 388 intptr_t cpu_registers_; |
| 382 intptr_t xmm_registers_; | 389 intptr_t fpu_registers_; |
| 383 | 390 |
| 384 DISALLOW_COPY_AND_ASSIGN(RegisterSet); | 391 DISALLOW_COPY_AND_ASSIGN(RegisterSet); |
| 385 }; | 392 }; |
| 386 | 393 |
| 387 | 394 |
| 388 // Specification of locations for inputs and output. | 395 // Specification of locations for inputs and output. |
| 389 class LocationSummary : public ZoneAllocated { | 396 class LocationSummary : public ZoneAllocated { |
| 390 public: | 397 public: |
| 391 enum ContainsCall { | 398 enum ContainsCall { |
| 392 kNoCall, | 399 kNoCall, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 BitmapBuilder* stack_bitmap_; | 485 BitmapBuilder* stack_bitmap_; |
| 479 | 486 |
| 480 const ContainsCall contains_call_; | 487 const ContainsCall contains_call_; |
| 481 RegisterSet live_registers_; | 488 RegisterSet live_registers_; |
| 482 }; | 489 }; |
| 483 | 490 |
| 484 | 491 |
| 485 } // namespace dart | 492 } // namespace dart |
| 486 | 493 |
| 487 #endif // VM_LOCATIONS_H_ | 494 #endif // VM_LOCATIONS_H_ |
| OLD | NEW |