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