| 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 |