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