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