| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 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 = 3, |
| 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 static const intptr_t kStackIndexBias = | |
| 37 static_cast<intptr_t>(1) << (kBitsForPayload - 1); | |
| 38 | 36 |
| 39 static const intptr_t kMachineRegisterMask = 0x6; | 37 static const intptr_t kMachineRegisterMask = 0x6; |
| 40 static const intptr_t kMachineRegister = 0x6; | 38 static const intptr_t kMachineRegister = 0x6; |
| 41 | 39 |
| 42 public: | 40 public: |
| 43 // Constant payload can overlap with kind field so Kind values | 41 // Constant payload can overlap with kind field so Kind values |
| 44 // have to be chosen in a way that their last 2 bits are never | 42 // have to be chosen in a way that their last 2 bits are never |
| 45 // the same as kConstant. | 43 // the same as kConstant. |
| 46 enum Kind { | 44 enum Kind { |
| 47 // This location is invalid. Payload must be zero. | 45 // This location is invalid. Payload must be zero. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 return Location(); | 147 return Location(); |
| 150 } | 148 } |
| 151 | 149 |
| 152 Policy policy() const { | 150 Policy policy() const { |
| 153 ASSERT(IsUnallocated()); | 151 ASSERT(IsUnallocated()); |
| 154 return PolicyField::decode(payload()); | 152 return PolicyField::decode(payload()); |
| 155 } | 153 } |
| 156 | 154 |
| 157 // Register locations. | 155 // Register locations. |
| 158 static Location RegisterLocation(Register reg) { | 156 static Location RegisterLocation(Register reg) { |
| 159 return Location(kRegister, static_cast<uword>(reg)); | 157 uword payload = |
| 158 RegisterField::encode(reg) | |
| 159 RepresentationField::encode(kDouble); // Unused for Register. |
| 160 return Location(kRegister, payload); |
| 160 } | 161 } |
| 161 | 162 |
| 162 bool IsRegister() const { | 163 bool IsRegister() const { |
| 163 return kind() == kRegister; | 164 return kind() == kRegister; |
| 164 } | 165 } |
| 165 | 166 |
| 166 Register reg() const { | 167 Register reg() const { |
| 167 ASSERT(IsRegister()); | 168 ASSERT(IsRegister()); |
| 168 return static_cast<Register>(payload()); | 169 return RegisterField::decode(payload()); |
| 170 } |
| 171 |
| 172 // XMM registers and double spill slots can contain either doubles |
| 173 // or 64-bit integers. |
| 174 enum Representation { |
| 175 kDouble, |
| 176 kMint |
| 177 }; |
| 178 |
| 179 Representation representation() const { |
| 180 ASSERT(IsXmmRegister() || IsDoubleStackSlot()); |
| 181 return RepresentationField::decode(payload()); |
| 169 } | 182 } |
| 170 | 183 |
| 171 // XmmRegister locations. | 184 // XmmRegister locations. |
| 172 static Location XmmRegisterLocation(XmmRegister reg) { | 185 static Location XmmRegisterLocation(XmmRegister reg, Representation rep) { |
| 173 return Location(kXmmRegister, static_cast<uword>(reg)); | 186 uword payload = |
| 187 XmmRegisterField::encode(reg) | RepresentationField::encode(rep); |
| 188 return Location(kXmmRegister, payload); |
| 174 } | 189 } |
| 175 | 190 |
| 176 bool IsXmmRegister() const { | 191 bool IsXmmRegister() const { |
| 177 return kind() == kXmmRegister; | 192 return kind() == kXmmRegister; |
| 178 } | 193 } |
| 179 | 194 |
| 180 XmmRegister xmm_reg() const { | 195 XmmRegister xmm_reg() const { |
| 181 ASSERT(IsXmmRegister()); | 196 ASSERT(IsXmmRegister()); |
| 182 return static_cast<XmmRegister>(payload()); | 197 return XmmRegisterField::decode(payload()); |
| 183 } | 198 } |
| 184 | 199 |
| 185 static bool IsMachineRegisterKind(Kind kind) { | 200 static bool IsMachineRegisterKind(Kind kind) { |
| 186 return (kind & kMachineRegisterMask) == kMachineRegister; | 201 return (kind & kMachineRegisterMask) == kMachineRegister; |
| 187 } | 202 } |
| 188 | 203 |
| 189 static Location MachineRegisterLocation(Kind kind, intptr_t reg) { | 204 static Location MachineRegisterLocation(Kind kind, |
| 190 return Location(kind, reg); | 205 intptr_t reg, |
| 206 Representation rep) { |
| 207 if (kind == kRegister) { |
| 208 return RegisterLocation(static_cast<Register>(reg)); |
| 209 } else { |
| 210 ASSERT(kind == kXmmRegister); |
| 211 return XmmRegisterLocation(static_cast<XmmRegister>(reg), rep); |
| 212 } |
| 191 } | 213 } |
| 192 | 214 |
| 193 bool IsMachineRegister() const { | 215 bool IsMachineRegister() const { |
| 194 return IsMachineRegisterKind(kind()); | 216 return IsMachineRegisterKind(kind()); |
| 195 } | 217 } |
| 196 | 218 |
| 197 intptr_t register_code() const { | 219 intptr_t register_code() const { |
| 198 ASSERT(IsMachineRegister()); | 220 ASSERT(IsMachineRegister()); |
| 199 return static_cast<intptr_t>(payload()); | 221 return static_cast<intptr_t>(RegisterField::decode(payload())); |
| 200 } | 222 } |
| 201 | 223 |
| 202 // Spill slots. | 224 // Spill slots. |
| 203 static Location StackSlot(intptr_t stack_index) { | 225 static Location StackSlot(intptr_t stack_index, |
| 226 Representation rep = kDouble) { |
| 204 ASSERT((-kStackIndexBias <= stack_index) && | 227 ASSERT((-kStackIndexBias <= stack_index) && |
| 205 (stack_index < kStackIndexBias)); | 228 (stack_index < kStackIndexBias)); |
| 206 Location loc(kStackSlot, static_cast<uword>(kStackIndexBias + stack_index)); | 229 uword payload = |
| 230 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) |
| 231 | RepresentationField::encode(rep); |
| 232 Location loc(kStackSlot, payload); |
| 207 // Ensure that sign is preserved. | 233 // Ensure that sign is preserved. |
| 208 ASSERT(loc.stack_index() == stack_index); | 234 ASSERT(loc.stack_index() == stack_index); |
| 209 return loc; | 235 return loc; |
| 210 } | 236 } |
| 211 | 237 |
| 212 bool IsStackSlot() const { | 238 bool IsStackSlot() const { |
| 213 return kind() == kStackSlot; | 239 return kind() == kStackSlot; |
| 214 } | 240 } |
| 215 | 241 |
| 216 static Location DoubleStackSlot(intptr_t stack_index) { | 242 static Location DoubleStackSlot(intptr_t stack_index, Representation rep) { |
| 217 ASSERT((-kStackIndexBias <= stack_index) && | 243 ASSERT((-kStackIndexBias <= stack_index) && |
| 218 (stack_index < kStackIndexBias)); | 244 (stack_index < kStackIndexBias)); |
| 219 Location loc(kDoubleStackSlot, | 245 uword payload = |
| 220 static_cast<uword>(kStackIndexBias + stack_index)); | 246 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index)) |
| 247 | RepresentationField::encode(rep); |
| 248 Location loc(kDoubleStackSlot, payload); |
| 221 // Ensure that sign is preserved. | 249 // Ensure that sign is preserved. |
| 222 ASSERT(loc.stack_index() == stack_index); | 250 ASSERT(loc.stack_index() == stack_index); |
| 223 return loc; | 251 return loc; |
| 224 } | 252 } |
| 225 | 253 |
| 226 bool IsDoubleStackSlot() const { | 254 bool IsDoubleStackSlot() const { |
| 227 return kind() == kDoubleStackSlot; | 255 return kind() == kDoubleStackSlot; |
| 228 } | 256 } |
| 229 | 257 |
| 230 | 258 |
| 231 intptr_t stack_index() const { | 259 intptr_t stack_index() const { |
| 232 ASSERT(IsStackSlot() || IsDoubleStackSlot()); | 260 ASSERT(IsStackSlot() || IsDoubleStackSlot()); |
| 233 // Decode stack index manually to preserve sign. | 261 // Decode stack index manually to preserve sign. |
| 234 return payload() - kStackIndexBias; | 262 return IndexField::decode(payload()) - kStackIndexBias; |
| 235 } | 263 } |
| 236 | 264 |
| 237 // Constants. | 265 // Constants. |
| 238 static Location RegisterOrConstant(Value* value); | 266 static Location RegisterOrConstant(Value* value); |
| 239 static Location FixedRegisterOrConstant(Value* value, Register reg); | 267 static Location FixedRegisterOrConstant(Value* value, Register reg); |
| 240 | 268 |
| 241 const char* Name() const; | 269 const char* Name() const; |
| 242 void PrintTo(BufferFormatter* f) const; | 270 void PrintTo(BufferFormatter* f) const; |
| 243 void Print() const; | 271 void Print() const; |
| 244 | 272 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 262 Kind kind() const { | 290 Kind kind() const { |
| 263 return KindField::decode(value_); | 291 return KindField::decode(value_); |
| 264 } | 292 } |
| 265 | 293 |
| 266 typedef BitField<Kind, 0, kBitsForKind> KindField; | 294 typedef BitField<Kind, 0, kBitsForKind> KindField; |
| 267 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; | 295 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; |
| 268 | 296 |
| 269 // Layout for kUnallocated locations payload. | 297 // Layout for kUnallocated locations payload. |
| 270 typedef BitField<Policy, 0, 3> PolicyField; | 298 typedef BitField<Policy, 0, 3> PolicyField; |
| 271 | 299 |
| 300 // Layout for register locations payload. The representation bit is only used |
| 301 // for XmmRegister and unused for Register. |
| 302 static const intptr_t kBitsForRepresentation = 1; |
| 303 static const intptr_t kBitsForRegister = |
| 304 kBitsForPayload - kBitsForRepresentation; |
| 305 typedef BitField<Representation, |
| 306 0, |
| 307 kBitsForRepresentation> RepresentationField; |
| 308 typedef BitField<Register, |
| 309 kBitsForRepresentation, |
| 310 kBitsForRegister> RegisterField; |
| 311 typedef BitField<XmmRegister, |
| 312 kBitsForRepresentation, |
| 313 kBitsForRegister> XmmRegisterField; |
| 314 |
| 315 // Layout for stack slots. The representation bit is only used for |
| 316 // DoubleStackSlot and unused for StackSlot. |
| 317 static const intptr_t kBitsForIndex = |
| 318 kBitsForPayload - kBitsForRepresentation; |
| 319 typedef BitField<uword, |
| 320 kBitsForRepresentation, |
| 321 kBitsForIndex> IndexField; |
| 322 static const intptr_t kStackIndexBias = |
| 323 static_cast<intptr_t>(1) << (kBitsForIndex - 1); |
| 324 |
| 272 // Location either contains kind and payload fields or a tagged handle for | 325 // Location either contains kind and payload fields or a tagged handle for |
| 273 // a constant locations. Values of enumeration Kind are selected in such a | 326 // a constant locations. Values of enumeration Kind are selected in such a |
| 274 // way that none of them can be interpreted as a kConstant tag. | 327 // way that none of them can be interpreted as a kConstant tag. |
| 275 uword value_; | 328 uword value_; |
| 276 }; | 329 }; |
| 277 | 330 |
| 278 | 331 |
| 279 class RegisterSet : public ValueObject { | 332 class RegisterSet : public ValueObject { |
| 280 public: | 333 public: |
| 281 RegisterSet() : cpu_registers_(0), xmm_registers_(0) { | 334 RegisterSet() : cpu_registers_(0), xmm_registers_(0) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 BitmapBuilder* stack_bitmap_; | 467 BitmapBuilder* stack_bitmap_; |
| 415 | 468 |
| 416 const ContainsCall contains_call_; | 469 const ContainsCall contains_call_; |
| 417 RegisterSet live_registers_; | 470 RegisterSet live_registers_; |
| 418 }; | 471 }; |
| 419 | 472 |
| 420 | 473 |
| 421 } // namespace dart | 474 } // namespace dart |
| 422 | 475 |
| 423 #endif // VM_LOCATIONS_H_ | 476 #endif // VM_LOCATIONS_H_ |
| OLD | NEW |