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 |