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" |
11 | 11 |
12 namespace dart { | 12 namespace dart { |
13 | 13 |
14 class BufferFormatter; | 14 class BufferFormatter; |
15 class Value; | 15 class Value; |
16 | 16 |
| 17 |
| 18 enum Representation { |
| 19 kNoRepresentation, |
| 20 kTagged, |
| 21 kUntagged, |
| 22 kUnboxedDouble, |
| 23 kUnboxedMint, |
| 24 kNumRepresentations |
| 25 }; |
| 26 |
| 27 |
17 // Location objects are used to connect register allocator and code generator. | 28 // Location objects are used to connect register allocator and code generator. |
18 // Instruction templates used by code generator have a corresponding | 29 // Instruction templates used by code generator have a corresponding |
19 // LocationSummary object which specifies expected location for every input | 30 // LocationSummary object which specifies expected location for every input |
20 // and output. | 31 // and output. |
21 // Each location is encoded as a single word: for non-constant locations | 32 // Each location is encoded as a single word: for non-constant locations |
22 // low 3 bits denote location kind, rest is kind specific location payload | 33 // low 3 bits denote location kind, rest is kind specific location payload |
23 // e.g. for REGISTER kind payload is register code (value of the Register | 34 // e.g. for REGISTER kind payload is register code (value of the Register |
24 // enumeration), constant locations contain a tagged (low 2 bits are set to 01) | 35 // enumeration), constant locations contain a tagged (low 2 bits are set to 01) |
25 // Object handle | 36 // Object handle |
26 class Location : public ValueObject { | 37 class Location : public ValueObject { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 static Location NoLocation() { | 164 static Location NoLocation() { |
154 return Location(); | 165 return Location(); |
155 } | 166 } |
156 | 167 |
157 Policy policy() const { | 168 Policy policy() const { |
158 ASSERT(IsUnallocated()); | 169 ASSERT(IsUnallocated()); |
159 return PolicyField::decode(payload()); | 170 return PolicyField::decode(payload()); |
160 } | 171 } |
161 | 172 |
162 // Register locations. | 173 // Register locations. |
163 static Location RegisterLocation(Register reg) { | 174 static Location RegisterLocation(Register reg, Representation rep = kTagged) { |
164 uword payload = | 175 uword payload = |
165 RegisterField::encode(reg) | | 176 RegisterField::encode(reg) | |
166 RepresentationField::encode(kDouble); // Unused for Register. | 177 RepresentationField::encode(rep); |
167 return Location(kRegister, payload); | 178 return Location(kRegister, payload); |
168 } | 179 } |
169 | 180 |
170 bool IsRegister() const { | 181 bool IsRegister() const { |
171 return kind() == kRegister; | 182 return kind() == kRegister; |
172 } | 183 } |
173 | 184 |
174 Register reg() const { | 185 Register reg() const { |
175 ASSERT(IsRegister()); | 186 ASSERT(IsRegister()); |
176 return RegisterField::decode(payload()); | 187 return RegisterField::decode(payload()); |
177 } | 188 } |
178 | 189 |
179 // FPU registers and double spill slots can contain either doubles | |
180 // or 64-bit integers. | |
181 enum Representation { | |
182 kDouble, | |
183 kMint | |
184 }; | |
185 | |
186 Representation representation() const { | 190 Representation representation() const { |
187 ASSERT(IsFpuRegister() || IsDoubleStackSlot()); | |
188 return RepresentationField::decode(payload()); | 191 return RepresentationField::decode(payload()); |
189 } | 192 } |
190 | 193 |
191 // FpuRegister locations. | 194 // FpuRegister locations. |
192 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { | 195 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { |
193 uword payload = | 196 uword payload = |
194 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); | 197 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); |
195 return Location(kFpuRegister, payload); | 198 return Location(kFpuRegister, payload); |
196 } | 199 } |
197 | 200 |
(...skipping 25 matching lines...) Expand all Loading... |
223 return IsMachineRegisterKind(kind()); | 226 return IsMachineRegisterKind(kind()); |
224 } | 227 } |
225 | 228 |
226 intptr_t register_code() const { | 229 intptr_t register_code() const { |
227 ASSERT(IsMachineRegister()); | 230 ASSERT(IsMachineRegister()); |
228 return static_cast<intptr_t>(RegisterField::decode(payload())); | 231 return static_cast<intptr_t>(RegisterField::decode(payload())); |
229 } | 232 } |
230 | 233 |
231 // Spill slots. | 234 // Spill slots. |
232 static Location StackSlot(intptr_t stack_index, | 235 static Location StackSlot(intptr_t stack_index, |
233 Representation rep = kDouble) { | 236 Representation rep = kTagged) { |
234 ASSERT((-kStackIndexBias <= stack_index) && | 237 ASSERT((-kStackIndexBias <= stack_index) && |
235 (stack_index < kStackIndexBias)); | 238 (stack_index < kStackIndexBias)); |
236 uword payload = | 239 uword payload = |
237 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | 240 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) |
238 | RepresentationField::encode(rep); | 241 | RepresentationField::encode(rep); |
239 Location loc(kStackSlot, payload); | 242 Location loc(kStackSlot, payload); |
240 // Ensure that sign is preserved. | 243 // Ensure that sign is preserved. |
241 ASSERT(loc.stack_index() == stack_index); | 244 ASSERT(loc.stack_index() == stack_index); |
242 return loc; | 245 return loc; |
243 } | 246 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 uword payload() const { | 306 uword payload() const { |
304 return PayloadField::decode(value_); | 307 return PayloadField::decode(value_); |
305 } | 308 } |
306 | 309 |
307 typedef BitField<Kind, 0, kBitsForKind> KindField; | 310 typedef BitField<Kind, 0, kBitsForKind> KindField; |
308 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 311 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
309 | 312 |
310 // Layout for kUnallocated locations payload. | 313 // Layout for kUnallocated locations payload. |
311 typedef BitField<Policy, 0, 3> PolicyField; | 314 typedef BitField<Policy, 0, 3> PolicyField; |
312 | 315 |
313 // Layout for register locations payload. The representation bit is only used | 316 // Layout for register locations payload. |
314 // for FpuRegister and unused for Register. | 317 static const intptr_t kBitsForRepresentation = 3; |
315 static const intptr_t kBitsForRepresentation = 1; | 318 COMPILE_ASSERT(kNumRepresentations <= (1 << kBitsForRepresentation), |
| 319 invalid_enum); |
316 static const intptr_t kBitsForRegister = | 320 static const intptr_t kBitsForRegister = |
317 kBitsForPayload - kBitsForRepresentation; | 321 kBitsForPayload - kBitsForRepresentation; |
318 typedef BitField<Representation, | 322 typedef BitField<Representation, |
319 0, | 323 0, |
320 kBitsForRepresentation> RepresentationField; | 324 kBitsForRepresentation> RepresentationField; |
321 typedef BitField<Register, | 325 typedef BitField<Register, |
322 kBitsForRepresentation, | 326 kBitsForRepresentation, |
323 kBitsForRegister> RegisterField; | 327 kBitsForRegister> RegisterField; |
324 typedef BitField<FpuRegister, | 328 typedef BitField<FpuRegister, |
325 kBitsForRepresentation, | 329 kBitsForRepresentation, |
326 kBitsForRegister> FpuRegisterField; | 330 kBitsForRegister> FpuRegisterField; |
327 | 331 |
328 // Layout for stack slots. The representation bit is only used for | 332 // Layout for stack slots. |
329 // DoubleStackSlot and unused for StackSlot. | |
330 static const intptr_t kBitsForIndex = | 333 static const intptr_t kBitsForIndex = |
331 kBitsForPayload - kBitsForRepresentation; | 334 kBitsForPayload - kBitsForRepresentation; |
332 typedef BitField<uword, | 335 typedef BitField<uword, |
333 kBitsForRepresentation, | 336 kBitsForRepresentation, |
334 kBitsForIndex> IndexField; | 337 kBitsForIndex> IndexField; |
335 static const intptr_t kStackIndexBias = | 338 static const intptr_t kStackIndexBias = |
336 static_cast<intptr_t>(1) << (kBitsForIndex - 1); | 339 static_cast<intptr_t>(1) << (kBitsForIndex - 1); |
337 | 340 |
338 // Location either contains kind and payload fields or a tagged handle for | 341 // Location either contains kind and payload fields or a tagged handle for |
339 // a constant locations. Values of enumeration Kind are selected in such a | 342 // a constant locations. Values of enumeration Kind are selected in such a |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 BitmapBuilder* stack_bitmap_; | 491 BitmapBuilder* stack_bitmap_; |
489 | 492 |
490 const ContainsCall contains_call_; | 493 const ContainsCall contains_call_; |
491 RegisterSet live_registers_; | 494 RegisterSet live_registers_; |
492 }; | 495 }; |
493 | 496 |
494 | 497 |
495 } // namespace dart | 498 } // namespace dart |
496 | 499 |
497 #endif // VM_LOCATIONS_H_ | 500 #endif // VM_LOCATIONS_H_ |
OLD | NEW |