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 |