Chromium Code Reviews| 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 = 9, | |
|
Vyacheslav Egorov (Google)
2013/03/17 18:17:10
It can't be 9 (see the comment above enum Kind).
Cutch
2013/03/17 21:52:37
Done.
| |
| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 Location loc(kDoubleStackSlot, payload); | 260 Location loc(kDoubleStackSlot, payload); |
| 256 // Ensure that sign is preserved. | 261 // Ensure that sign is preserved. |
| 257 ASSERT(loc.stack_index() == stack_index); | 262 ASSERT(loc.stack_index() == stack_index); |
| 258 return loc; | 263 return loc; |
| 259 } | 264 } |
| 260 | 265 |
| 261 bool IsDoubleStackSlot() const { | 266 bool IsDoubleStackSlot() const { |
| 262 return kind() == kDoubleStackSlot; | 267 return kind() == kDoubleStackSlot; |
| 263 } | 268 } |
| 264 | 269 |
| 270 static Location Float32x4StackSlot(intptr_t stack_index, Representation rep) { | |
| 271 ASSERT((-kStackIndexBias <= stack_index) && | |
| 272 (stack_index < kStackIndexBias)); | |
| 273 uword payload = | |
| 274 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | |
|
Vyacheslav Egorov (Google)
2013/03/17 18:17:10
encoding of stack indexes repeats multiple times.
Cutch
2013/03/17 21:52:37
Done.
| |
| 275 | RepresentationField::encode(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 ASSERT((-kStackIndexBias <= stack_index) && | |
| 288 (stack_index < kStackIndexBias)); | |
| 289 uword payload = | |
| 290 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) | |
| 291 | RepresentationField::encode(rep); | |
| 292 Location loc(kUint32x4StackSlot, payload); | |
| 293 // Ensure that sign is preserved. | |
| 294 ASSERT(loc.stack_index() == stack_index); | |
| 295 return loc; | |
| 296 } | |
| 297 | |
| 298 bool IsUint32x4StackSlot() const { | |
| 299 return kind() == kUint32x4StackSlot; | |
| 300 } | |
| 301 | |
| 265 | 302 |
| 266 intptr_t stack_index() const { | 303 intptr_t stack_index() const { |
| 267 ASSERT(IsStackSlot() || IsDoubleStackSlot()); | 304 ASSERT(IsStackSlot() || IsDoubleStackSlot() || IsFloat32x4StackSlot() || |
| 305 IsUint32x4StackSlot()); | |
| 268 // Decode stack index manually to preserve sign. | 306 // Decode stack index manually to preserve sign. |
| 269 return IndexField::decode(payload()) - kStackIndexBias; | 307 return IndexField::decode(payload()) - kStackIndexBias; |
| 270 } | 308 } |
| 271 | 309 |
| 272 // Return a memory operand for stack slot locations. | 310 // Return a memory operand for stack slot locations. |
| 273 Address ToStackSlotAddress() const; | 311 Address ToStackSlotAddress() const; |
| 274 | 312 |
| 275 // Constants. | 313 // Constants. |
| 276 static Location RegisterOrConstant(Value* value); | 314 static Location RegisterOrConstant(Value* value); |
| 277 static Location RegisterOrSmiConstant(Value* value); | 315 static Location RegisterOrSmiConstant(Value* value); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 305 } | 343 } |
| 306 | 344 |
| 307 typedef BitField<Kind, 0, kBitsForKind> KindField; | 345 typedef BitField<Kind, 0, kBitsForKind> KindField; |
| 308 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 346 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
| 309 | 347 |
| 310 // Layout for kUnallocated locations payload. | 348 // Layout for kUnallocated locations payload. |
| 311 typedef BitField<Policy, 0, 3> PolicyField; | 349 typedef BitField<Policy, 0, 3> PolicyField; |
| 312 | 350 |
| 313 // Layout for register locations payload. The representation bit is only used | 351 // Layout for register locations payload. The representation bit is only used |
| 314 // for FpuRegister and unused for Register. | 352 // for FpuRegister and unused for Register. |
| 315 static const intptr_t kBitsForRepresentation = 1; | 353 static const intptr_t kBitsForRepresentation = 2; |
| 316 static const intptr_t kBitsForRegister = | 354 static const intptr_t kBitsForRegister = |
| 317 kBitsForPayload - kBitsForRepresentation; | 355 kBitsForPayload - kBitsForRepresentation; |
| 318 typedef BitField<Representation, | 356 typedef BitField<Representation, |
| 319 0, | 357 0, |
| 320 kBitsForRepresentation> RepresentationField; | 358 kBitsForRepresentation> RepresentationField; |
| 321 typedef BitField<Register, | 359 typedef BitField<Register, |
| 322 kBitsForRepresentation, | 360 kBitsForRepresentation, |
| 323 kBitsForRegister> RegisterField; | 361 kBitsForRegister> RegisterField; |
| 324 typedef BitField<FpuRegister, | 362 typedef BitField<FpuRegister, |
| 325 kBitsForRepresentation, | 363 kBitsForRepresentation, |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 BitmapBuilder* stack_bitmap_; | 526 BitmapBuilder* stack_bitmap_; |
| 489 | 527 |
| 490 const ContainsCall contains_call_; | 528 const ContainsCall contains_call_; |
| 491 RegisterSet live_registers_; | 529 RegisterSet live_registers_; |
| 492 }; | 530 }; |
| 493 | 531 |
| 494 | 532 |
| 495 } // namespace dart | 533 } // namespace dart |
| 496 | 534 |
| 497 #endif // VM_LOCATIONS_H_ | 535 #endif // VM_LOCATIONS_H_ |
| OLD | NEW |