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 | 17 |
18 enum Representation { | 18 enum Representation { |
19 kNoRepresentation, | 19 kNoRepresentation, |
20 kTagged, | 20 kTagged, |
21 kUntagged, | 21 kUntagged, |
22 kUnboxedDouble, | 22 kUnboxedDouble, |
23 kUnboxedMint, | 23 kUnboxedMint, |
| 24 kUnboxedFloat32x4, |
| 25 kUnboxedUint32x4, |
24 kNumRepresentations | 26 kNumRepresentations |
25 }; | 27 }; |
26 | 28 |
27 | 29 |
28 // Location objects are used to connect register allocator and code generator. | 30 // Location objects are used to connect register allocator and code generator. |
29 // Instruction templates used by code generator have a corresponding | 31 // Instruction templates used by code generator have a corresponding |
30 // LocationSummary object which specifies expected location for every input | 32 // LocationSummary object which specifies expected location for every input |
31 // and output. | 33 // and output. |
32 // Each location is encoded as a single word: for non-constant locations | 34 // Each location is encoded as a single word: for non-constant locations |
33 // low 3 bits denote location kind, rest is kind specific location payload | 35 // low 3 bits denote location kind, rest is kind specific location payload |
34 // e.g. for REGISTER kind payload is register code (value of the Register | 36 // e.g. for REGISTER kind payload is register code (value of the Register |
35 // enumeration), constant locations contain a tagged (low 2 bits are set to 01) | 37 // enumeration), constant locations contain a tagged (low 2 bits are set to 01) |
36 // Object handle | 38 // Object handle |
37 class Location : public ValueObject { | 39 class Location : public ValueObject { |
38 private: | 40 private: |
39 enum { | 41 enum { |
40 // Number of bits required to encode Kind value. | 42 // Number of bits required to encode Kind value. |
41 kBitsForKind = 3, | 43 kBitsForKind = 4, |
42 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, | 44 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, |
43 }; | 45 }; |
44 | 46 |
45 static const uword kInvalidLocation = 0; | 47 static const uword kInvalidLocation = 0; |
46 static const uword kConstantMask = 0x3; | 48 static const uword kConstantMask = 0x3; |
47 | 49 |
48 static const intptr_t kMachineRegisterMask = 0x6; | 50 static const intptr_t kMachineRegisterMask = 0x6; |
49 static const intptr_t kMachineRegister = 0x6; | 51 static const intptr_t kMachineRegister = 0x6; |
50 | 52 |
51 public: | 53 public: |
(...skipping 10 matching lines...) Expand all Loading... |
62 // Unallocated location represents a location that is not fixed and can be | 64 // Unallocated location represents a location that is not fixed and can be |
63 // allocated by a register allocator. Each unallocated location has | 65 // allocated by a register allocator. Each unallocated location has |
64 // a policy that specifies what kind of location is suitable. Payload | 66 // a policy that specifies what kind of location is suitable. Payload |
65 // contains register allocation policy. | 67 // contains register allocation policy. |
66 kUnallocated = 2, | 68 kUnallocated = 2, |
67 | 69 |
68 // Spill slot allocated by the register allocator. Payload contains | 70 // Spill slot allocated by the register allocator. Payload contains |
69 // a spill index. | 71 // a spill index. |
70 kStackSlot = 3, | 72 kStackSlot = 3, |
71 kDoubleStackSlot = 4, | 73 kDoubleStackSlot = 4, |
| 74 kFloat32x4StackSlot = 8, |
| 75 kUint32x4StackSlot = 10, |
72 | 76 |
73 // Register location represents a fixed register. Payload contains | 77 // Register location represents a fixed register. Payload contains |
74 // register code. | 78 // register code. |
75 kRegister = 6, | 79 kRegister = 6, |
76 | 80 |
77 // FpuRegister location represents a fixed fpu register. Payload contains | 81 // FpuRegister location represents a fixed fpu register. Payload contains |
78 // its code. | 82 // its code. |
79 kFpuRegister = 7, | 83 kFpuRegister = 7, |
80 }; | 84 }; |
81 | 85 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 | 184 |
181 bool IsRegister() const { | 185 bool IsRegister() const { |
182 return kind() == kRegister; | 186 return kind() == kRegister; |
183 } | 187 } |
184 | 188 |
185 Register reg() const { | 189 Register reg() const { |
186 ASSERT(IsRegister()); | 190 ASSERT(IsRegister()); |
187 return RegisterField::decode(payload()); | 191 return RegisterField::decode(payload()); |
188 } | 192 } |
189 | 193 |
| 194 |
190 Representation representation() const { | 195 Representation representation() const { |
191 return RepresentationField::decode(payload()); | 196 return RepresentationField::decode(payload()); |
192 } | 197 } |
193 | 198 |
194 // FpuRegister locations. | 199 // FpuRegister locations. |
195 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { | 200 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { |
196 uword payload = | 201 uword payload = |
197 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); | 202 FpuRegisterField::encode(reg) | RepresentationField::encode(rep); |
198 return Location(kFpuRegister, payload); | 203 return Location(kFpuRegister, payload); |
199 } | 204 } |
(...skipping 24 matching lines...) Expand all Loading... |
224 | 229 |
225 bool IsMachineRegister() const { | 230 bool IsMachineRegister() const { |
226 return IsMachineRegisterKind(kind()); | 231 return IsMachineRegisterKind(kind()); |
227 } | 232 } |
228 | 233 |
229 intptr_t register_code() const { | 234 intptr_t register_code() const { |
230 ASSERT(IsMachineRegister()); | 235 ASSERT(IsMachineRegister()); |
231 return static_cast<intptr_t>(RegisterField::decode(payload())); | 236 return static_cast<intptr_t>(RegisterField::decode(payload())); |
232 } | 237 } |
233 | 238 |
| 239 static uword make_stack_index_payload(intptr_t stack_index, |
| 240 Representation rep) { |
| 241 ASSERT((-kStackIndexBias <= stack_index) && |
| 242 (stack_index < kStackIndexBias)); |
| 243 uword payload = |
| 244 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)); |
| 245 return payload | RepresentationField::encode(rep); |
| 246 } |
| 247 |
234 // Spill slots. | 248 // Spill slots. |
235 static Location StackSlot(intptr_t stack_index, | 249 static Location StackSlot(intptr_t stack_index, |
236 Representation rep = kTagged) { | 250 Representation rep = kTagged) { |
237 ASSERT((-kStackIndexBias <= stack_index) && | 251 uword payload = make_stack_index_payload(stack_index, rep); |
238 (stack_index < kStackIndexBias)); | |
239 uword payload = | |
240 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | |
241 | RepresentationField::encode(rep); | |
242 Location loc(kStackSlot, payload); | 252 Location loc(kStackSlot, payload); |
243 // Ensure that sign is preserved. | 253 // Ensure that sign is preserved. |
244 ASSERT(loc.stack_index() == stack_index); | 254 ASSERT(loc.stack_index() == stack_index); |
245 return loc; | 255 return loc; |
246 } | 256 } |
247 | 257 |
248 bool IsStackSlot() const { | 258 bool IsStackSlot() const { |
249 return kind() == kStackSlot; | 259 return kind() == kStackSlot; |
250 } | 260 } |
251 | 261 |
252 static Location DoubleStackSlot(intptr_t stack_index, Representation rep) { | 262 static Location DoubleStackSlot(intptr_t stack_index, Representation rep) { |
253 ASSERT((-kStackIndexBias <= stack_index) && | 263 uword payload = make_stack_index_payload(stack_index, rep); |
254 (stack_index < kStackIndexBias)); | |
255 uword payload = | |
256 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | |
257 | RepresentationField::encode(rep); | |
258 Location loc(kDoubleStackSlot, payload); | 264 Location loc(kDoubleStackSlot, payload); |
259 // Ensure that sign is preserved. | 265 // Ensure that sign is preserved. |
260 ASSERT(loc.stack_index() == stack_index); | 266 ASSERT(loc.stack_index() == stack_index); |
261 return loc; | 267 return loc; |
262 } | 268 } |
263 | 269 |
264 bool IsDoubleStackSlot() const { | 270 bool IsDoubleStackSlot() const { |
265 return kind() == kDoubleStackSlot; | 271 return kind() == kDoubleStackSlot; |
266 } | 272 } |
267 | 273 |
| 274 static Location Float32x4StackSlot(intptr_t stack_index, Representation rep) { |
| 275 uword payload = make_stack_index_payload(stack_index, rep); |
| 276 Location loc(kFloat32x4StackSlot, payload); |
| 277 // Ensure that sign is preserved. |
| 278 ASSERT(loc.stack_index() == stack_index); |
| 279 return loc; |
| 280 } |
| 281 |
| 282 bool IsFloat32x4StackSlot() const { |
| 283 return kind() == kFloat32x4StackSlot; |
| 284 } |
| 285 |
| 286 static Location Uint32x4StackSlot(intptr_t stack_index, Representation rep) { |
| 287 uword payload = make_stack_index_payload(stack_index, rep); |
| 288 Location loc(kUint32x4StackSlot, payload); |
| 289 // Ensure that sign is preserved. |
| 290 ASSERT(loc.stack_index() == stack_index); |
| 291 return loc; |
| 292 } |
| 293 |
| 294 bool IsUint32x4StackSlot() const { |
| 295 return kind() == kUint32x4StackSlot; |
| 296 } |
| 297 |
268 | 298 |
269 intptr_t stack_index() const { | 299 intptr_t stack_index() const { |
270 ASSERT(IsStackSlot() || IsDoubleStackSlot()); | 300 ASSERT(IsStackSlot() || IsDoubleStackSlot() || IsFloat32x4StackSlot() || |
| 301 IsUint32x4StackSlot()); |
271 // Decode stack index manually to preserve sign. | 302 // Decode stack index manually to preserve sign. |
272 return IndexField::decode(payload()) - kStackIndexBias; | 303 return IndexField::decode(payload()) - kStackIndexBias; |
273 } | 304 } |
274 | 305 |
275 // Return a memory operand for stack slot locations. | 306 // Return a memory operand for stack slot locations. |
276 Address ToStackSlotAddress() const; | 307 Address ToStackSlotAddress() const; |
277 | 308 |
278 // Constants. | 309 // Constants. |
279 static Location RegisterOrConstant(Value* value); | 310 static Location RegisterOrConstant(Value* value); |
280 static Location RegisterOrSmiConstant(Value* value); | 311 static Location RegisterOrSmiConstant(Value* value); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 BitmapBuilder* stack_bitmap_; | 522 BitmapBuilder* stack_bitmap_; |
492 | 523 |
493 const ContainsCall contains_call_; | 524 const ContainsCall contains_call_; |
494 RegisterSet live_registers_; | 525 RegisterSet live_registers_; |
495 }; | 526 }; |
496 | 527 |
497 | 528 |
498 } // namespace dart | 529 } // namespace dart |
499 | 530 |
500 #endif // VM_LOCATIONS_H_ | 531 #endif // VM_LOCATIONS_H_ |
OLD | NEW |