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 // Location objects are used to connect register allocator and code generator. | 17 // Location objects are used to connect register allocator and code generator. |
18 // Instruction templates used by code generator have a corresponding | 18 // Instruction templates used by code generator have a corresponding |
19 // LocationSummary object which specifies expected location for every input | 19 // LocationSummary object which specifies expected location for every input |
20 // and output. | 20 // and output. |
21 // Each location is encoded as a single word: for non-constant locations | 21 // 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 | 22 // 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 | 23 // 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) | 24 // enumeration), constant locations contain a tagged (low 2 bits are set to 01) |
25 // Object handle | 25 // Object handle |
26 class Location : public ValueObject { | 26 class Location : public ValueObject { |
27 private: | 27 private: |
28 enum { | 28 enum { |
29 // Number of bits required to encode Kind value. | 29 // Number of bits required to encode Kind value. |
30 kBitsForKind = 3, | 30 kBitsForKind = 4, |
31 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, | 31 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, |
32 }; | 32 }; |
33 | 33 |
34 static const uword kInvalidLocation = 0; | 34 static const uword kInvalidLocation = 0; |
35 static const uword kConstantMask = 0x3; | 35 static const uword kConstantMask = 0x3; |
36 | 36 |
37 static const intptr_t kMachineRegisterMask = 0x6; | 37 static const intptr_t kMachineRegisterMask = 0x6; |
38 static const intptr_t kMachineRegister = 0x6; | 38 static const intptr_t kMachineRegister = 0x6; |
39 | 39 |
40 public: | 40 public: |
(...skipping 10 matching lines...) Expand all Loading... |
51 // Unallocated location represents a location that is not fixed and can be | 51 // Unallocated location represents a location that is not fixed and can be |
52 // allocated by a register allocator. Each unallocated location has | 52 // allocated by a register allocator. Each unallocated location has |
53 // a policy that specifies what kind of location is suitable. Payload | 53 // a policy that specifies what kind of location is suitable. Payload |
54 // contains register allocation policy. | 54 // contains register allocation policy. |
55 kUnallocated = 2, | 55 kUnallocated = 2, |
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 kFloat32x4StackSlot = 8, |
| 62 kUint32x4StackSlot = 10, |
61 | 63 |
62 // Register location represents a fixed register. Payload contains | 64 // Register location represents a fixed register. Payload contains |
63 // register code. | 65 // register code. |
64 kRegister = 6, | 66 kRegister = 6, |
65 | 67 |
66 // FpuRegister location represents a fixed fpu register. Payload contains | 68 // FpuRegister location represents a fixed fpu register. Payload contains |
67 // its code. | 69 // its code. |
68 kFpuRegister = 7, | 70 kFpuRegister = 7, |
69 }; | 71 }; |
70 | 72 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 171 |
170 bool IsRegister() const { | 172 bool IsRegister() const { |
171 return kind() == kRegister; | 173 return kind() == kRegister; |
172 } | 174 } |
173 | 175 |
174 Register reg() const { | 176 Register reg() const { |
175 ASSERT(IsRegister()); | 177 ASSERT(IsRegister()); |
176 return RegisterField::decode(payload()); | 178 return RegisterField::decode(payload()); |
177 } | 179 } |
178 | 180 |
179 // FPU registers and double spill slots can contain either doubles | 181 // FPU registers and double spill slots can contain either doubles, |
180 // or 64-bit integers. | 182 // 64-bit integers, Float32x4, or Uint32x4 values. |
181 enum Representation { | 183 enum Representation { |
182 kDouble, | 184 kDouble, |
183 kMint | 185 kMint, |
| 186 kFloat32x4, |
| 187 kUint32x4 |
184 }; | 188 }; |
185 | 189 |
186 Representation representation() const { | 190 Representation representation() const { |
187 ASSERT(IsFpuRegister() || IsDoubleStackSlot()); | 191 ASSERT(IsFpuRegister() ||IsDoubleStackSlot() || IsFloat32x4StackSlot() || |
| 192 IsUint32x4StackSlot()); |
188 return RepresentationField::decode(payload()); | 193 return RepresentationField::decode(payload()); |
189 } | 194 } |
190 | 195 |
191 // FpuRegister locations. | 196 // FpuRegister locations. |
192 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { | 197 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { |
193 uword payload = | 198 uword payload = |
194 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); | 199 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); |
195 return Location(kFpuRegister, payload); | 200 return Location(kFpuRegister, payload); |
196 } | 201 } |
197 | 202 |
(...skipping 23 matching lines...) Expand all Loading... |
221 | 226 |
222 bool IsMachineRegister() const { | 227 bool IsMachineRegister() const { |
223 return IsMachineRegisterKind(kind()); | 228 return IsMachineRegisterKind(kind()); |
224 } | 229 } |
225 | 230 |
226 intptr_t register_code() const { | 231 intptr_t register_code() const { |
227 ASSERT(IsMachineRegister()); | 232 ASSERT(IsMachineRegister()); |
228 return static_cast<intptr_t>(RegisterField::decode(payload())); | 233 return static_cast<intptr_t>(RegisterField::decode(payload())); |
229 } | 234 } |
230 | 235 |
| 236 static uword make_stack_index_payload(intptr_t stack_index, |
| 237 Representation rep) { |
| 238 ASSERT((-kStackIndexBias <= stack_index) && |
| 239 (stack_index < kStackIndexBias)); |
| 240 uword payload = |
| 241 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)); |
| 242 return payload | RepresentationField::encode(rep); |
| 243 } |
| 244 |
231 // Spill slots. | 245 // Spill slots. |
232 static Location StackSlot(intptr_t stack_index, | 246 static Location StackSlot(intptr_t stack_index, |
233 Representation rep = kDouble) { | 247 Representation rep = kDouble) { |
234 ASSERT((-kStackIndexBias <= stack_index) && | 248 uword payload = make_stack_index_payload(stack_index, rep); |
235 (stack_index < kStackIndexBias)); | |
236 uword payload = | |
237 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | |
238 | RepresentationField::encode(rep); | |
239 Location loc(kStackSlot, payload); | 249 Location loc(kStackSlot, payload); |
240 // Ensure that sign is preserved. | 250 // Ensure that sign is preserved. |
241 ASSERT(loc.stack_index() == stack_index); | 251 ASSERT(loc.stack_index() == stack_index); |
242 return loc; | 252 return loc; |
243 } | 253 } |
244 | 254 |
245 bool IsStackSlot() const { | 255 bool IsStackSlot() const { |
246 return kind() == kStackSlot; | 256 return kind() == kStackSlot; |
247 } | 257 } |
248 | 258 |
249 static Location DoubleStackSlot(intptr_t stack_index, Representation rep) { | 259 static Location DoubleStackSlot(intptr_t stack_index, Representation rep) { |
250 ASSERT((-kStackIndexBias <= stack_index) && | 260 uword payload = make_stack_index_payload(stack_index, rep); |
251 (stack_index < kStackIndexBias)); | |
252 uword payload = | |
253 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | |
254 | RepresentationField::encode(rep); | |
255 Location loc(kDoubleStackSlot, payload); | 261 Location loc(kDoubleStackSlot, payload); |
256 // Ensure that sign is preserved. | 262 // Ensure that sign is preserved. |
257 ASSERT(loc.stack_index() == stack_index); | 263 ASSERT(loc.stack_index() == stack_index); |
258 return loc; | 264 return loc; |
259 } | 265 } |
260 | 266 |
261 bool IsDoubleStackSlot() const { | 267 bool IsDoubleStackSlot() const { |
262 return kind() == kDoubleStackSlot; | 268 return kind() == kDoubleStackSlot; |
263 } | 269 } |
264 | 270 |
| 271 static Location Float32x4StackSlot(intptr_t stack_index, Representation rep) { |
| 272 uword payload = make_stack_index_payload(stack_index, rep); |
| 273 Location loc(kFloat32x4StackSlot, payload); |
| 274 // Ensure that sign is preserved. |
| 275 ASSERT(loc.stack_index() == stack_index); |
| 276 return loc; |
| 277 } |
| 278 |
| 279 bool IsFloat32x4StackSlot() const { |
| 280 return kind() == kFloat32x4StackSlot; |
| 281 } |
| 282 |
| 283 static Location Uint32x4StackSlot(intptr_t stack_index, Representation rep) { |
| 284 uword payload = make_stack_index_payload(stack_index, rep); |
| 285 Location loc(kUint32x4StackSlot, payload); |
| 286 // Ensure that sign is preserved. |
| 287 ASSERT(loc.stack_index() == stack_index); |
| 288 return loc; |
| 289 } |
| 290 |
| 291 bool IsUint32x4StackSlot() const { |
| 292 return kind() == kUint32x4StackSlot; |
| 293 } |
| 294 |
265 | 295 |
266 intptr_t stack_index() const { | 296 intptr_t stack_index() const { |
267 ASSERT(IsStackSlot() || IsDoubleStackSlot()); | 297 ASSERT(IsStackSlot() || IsDoubleStackSlot() || IsFloat32x4StackSlot() || |
| 298 IsUint32x4StackSlot()); |
268 // Decode stack index manually to preserve sign. | 299 // Decode stack index manually to preserve sign. |
269 return IndexField::decode(payload()) - kStackIndexBias; | 300 return IndexField::decode(payload()) - kStackIndexBias; |
270 } | 301 } |
271 | 302 |
272 // Return a memory operand for stack slot locations. | 303 // Return a memory operand for stack slot locations. |
273 Address ToStackSlotAddress() const; | 304 Address ToStackSlotAddress() const; |
274 | 305 |
275 // Constants. | 306 // Constants. |
276 static Location RegisterOrConstant(Value* value); | 307 static Location RegisterOrConstant(Value* value); |
277 static Location RegisterOrSmiConstant(Value* value); | 308 static Location RegisterOrSmiConstant(Value* value); |
(...skipping 27 matching lines...) Expand all Loading... |
305 } | 336 } |
306 | 337 |
307 typedef BitField<Kind, 0, kBitsForKind> KindField; | 338 typedef BitField<Kind, 0, kBitsForKind> KindField; |
308 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 339 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
309 | 340 |
310 // Layout for kUnallocated locations payload. | 341 // Layout for kUnallocated locations payload. |
311 typedef BitField<Policy, 0, 3> PolicyField; | 342 typedef BitField<Policy, 0, 3> PolicyField; |
312 | 343 |
313 // Layout for register locations payload. The representation bit is only used | 344 // Layout for register locations payload. The representation bit is only used |
314 // for FpuRegister and unused for Register. | 345 // for FpuRegister and unused for Register. |
315 static const intptr_t kBitsForRepresentation = 1; | 346 static const intptr_t kBitsForRepresentation = 2; |
316 static const intptr_t kBitsForRegister = | 347 static const intptr_t kBitsForRegister = |
317 kBitsForPayload - kBitsForRepresentation; | 348 kBitsForPayload - kBitsForRepresentation; |
318 typedef BitField<Representation, | 349 typedef BitField<Representation, |
319 0, | 350 0, |
320 kBitsForRepresentation> RepresentationField; | 351 kBitsForRepresentation> RepresentationField; |
321 typedef BitField<Register, | 352 typedef BitField<Register, |
322 kBitsForRepresentation, | 353 kBitsForRepresentation, |
323 kBitsForRegister> RegisterField; | 354 kBitsForRegister> RegisterField; |
324 typedef BitField<FpuRegister, | 355 typedef BitField<FpuRegister, |
325 kBitsForRepresentation, | 356 kBitsForRepresentation, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 BitmapBuilder* stack_bitmap_; | 519 BitmapBuilder* stack_bitmap_; |
489 | 520 |
490 const ContainsCall contains_call_; | 521 const ContainsCall contains_call_; |
491 RegisterSet live_registers_; | 522 RegisterSet live_registers_; |
492 }; | 523 }; |
493 | 524 |
494 | 525 |
495 } // namespace dart | 526 } // namespace dart |
496 | 527 |
497 #endif // VM_LOCATIONS_H_ | 528 #endif // VM_LOCATIONS_H_ |
OLD | NEW |