Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(685)

Side by Side Diff: runtime/vm/locations.h

Issue 13801014: Fix bug in ParallelMoveResolver::EmitSwap: implement swaps of FPU spill slots. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 17 matching lines...) Expand all
28 28
29 29
30 // Location objects are used to connect register allocator and code generator. 30 // Location objects are used to connect register allocator and code generator.
31 // Instruction templates used by code generator have a corresponding 31 // Instruction templates used by code generator have a corresponding
32 // LocationSummary object which specifies expected location for every input 32 // LocationSummary object which specifies expected location for every input
33 // and output. 33 // and output.
34 // 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
35 // 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
36 // 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
37 // 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)
38 // Object handle 38 // Object handle.
39 //
40 // Locations must satisfy the following invariant: if two locations' encodings
41 // are bitwise unequal then these two locations are guaranteed to be disjoint.
42 // Properties like representation belong to the value that is stored in
43 // the location not to the location itself.
39 class Location : public ValueObject { 44 class Location : public ValueObject {
40 private: 45 private:
41 enum { 46 enum {
42 // Number of bits required to encode Kind value. 47 // Number of bits required to encode Kind value.
43 kBitsForKind = 4, 48 kBitsForKind = 4,
44 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, 49 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind,
45 }; 50 };
46 51
47 static const uword kInvalidLocation = 0; 52 static const uword kInvalidLocation = 0;
48 static const uword kConstantMask = 0x3; 53 static const uword kConstantMask = 0x3;
49 54
50 static const intptr_t kMachineRegisterMask = 0x6; 55 static const intptr_t kMachineRegisterMask = 0x6;
51 static const intptr_t kMachineRegister = 0x6; 56 static const intptr_t kMachineRegister = 0x6;
52 57
53 public: 58 public:
54 // Constant payload can overlap with kind field so Kind values 59 // Constant payload can overlap with kind field so Kind values
55 // have to be chosen in a way that their last 2 bits are never 60 // have to be chosen in a way that their last 2 bits are never
56 // the same as kConstant. 61 // the same as kConstant.
62 // Note that two locations with different kinds should never point to
63 // the same place. For example kQuadStackSlot location should never intersect
64 // with kDoubleStackSlot location.
57 enum Kind { 65 enum Kind {
58 // This location is invalid. Payload must be zero. 66 // This location is invalid. Payload must be zero.
59 kInvalid = 0, 67 kInvalid = 0,
60 68
61 // Constant value. This location contains a tagged Object handle. 69 // Constant value. This location contains a tagged Object handle.
62 kConstant = 1, 70 kConstant = 1,
63 71
64 // Unallocated location represents a location that is not fixed and can be 72 // Unallocated location represents a location that is not fixed and can be
65 // allocated by a register allocator. Each unallocated location has 73 // allocated by a register allocator. Each unallocated location has
66 // a policy that specifies what kind of location is suitable. Payload 74 // a policy that specifies what kind of location is suitable. Payload
67 // contains register allocation policy. 75 // contains register allocation policy.
68 kUnallocated = 2, 76 kUnallocated = 2,
69 77
70 // Spill slot allocated by the register allocator. Payload contains 78 // Spill slots allocated by the register allocator. Payload contains
71 // a spill index. 79 // a spill index.
72 kStackSlot = 3, 80 kStackSlot = 3, // Word size slot.
73 kDoubleStackSlot = 4, 81 kDoubleStackSlot = 4, // 64bit stack slot.
74 kFloat32x4StackSlot = 8, 82 kQuadStackSlot = 8, // 128bit stack slot.
75 kUint32x4StackSlot = 10,
76 83
77 // Register location represents a fixed register. Payload contains 84 // Register location represents a fixed register. Payload contains
78 // register code. 85 // register code.
79 kRegister = 6, 86 kRegister = 6,
80 87
81 // FpuRegister location represents a fixed fpu register. Payload contains 88 // FpuRegister location represents a fixed fpu register. Payload contains
82 // its code. 89 // its code.
83 kFpuRegister = 7, 90 kFpuRegister = 7,
84 }; 91 };
85 92
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 static Location NoLocation() { 175 static Location NoLocation() {
169 return Location(); 176 return Location();
170 } 177 }
171 178
172 Policy policy() const { 179 Policy policy() const {
173 ASSERT(IsUnallocated()); 180 ASSERT(IsUnallocated());
174 return PolicyField::decode(payload()); 181 return PolicyField::decode(payload());
175 } 182 }
176 183
177 // Register locations. 184 // Register locations.
178 static Location RegisterLocation(Register reg, Representation rep = kTagged) { 185 static Location RegisterLocation(Register reg) {
179 uword payload = 186 return Location(kRegister, reg);
180 RegisterField::encode(reg) |
181 RepresentationField::encode(rep);
182 return Location(kRegister, payload);
183 } 187 }
184 188
185 bool IsRegister() const { 189 bool IsRegister() const {
186 return kind() == kRegister; 190 return kind() == kRegister;
187 } 191 }
188 192
189 Register reg() const { 193 Register reg() const {
190 ASSERT(IsRegister()); 194 ASSERT(IsRegister());
191 return RegisterField::decode(payload()); 195 return static_cast<Register>(payload());
192 }
193
194
195 Representation representation() const {
196 return RepresentationField::decode(payload());
197 } 196 }
198 197
199 // FpuRegister locations. 198 // FpuRegister locations.
200 static Location FpuRegisterLocation(FpuRegister reg, Representation rep) { 199 static Location FpuRegisterLocation(FpuRegister reg) {
201 uword payload = 200 return Location(kFpuRegister, reg);
202 FpuRegisterField::encode(reg) | RepresentationField::encode(rep);
203 return Location(kFpuRegister, payload);
204 } 201 }
205 202
206 bool IsFpuRegister() const { 203 bool IsFpuRegister() const {
207 return kind() == kFpuRegister; 204 return kind() == kFpuRegister;
208 } 205 }
209 206
210 FpuRegister fpu_reg() const { 207 FpuRegister fpu_reg() const {
211 ASSERT(IsFpuRegister()); 208 ASSERT(IsFpuRegister());
212 return FpuRegisterField::decode(payload()); 209 return static_cast<FpuRegister>(payload());
213 } 210 }
214 211
215 static bool IsMachineRegisterKind(Kind kind) { 212 static bool IsMachineRegisterKind(Kind kind) {
216 return (kind & kMachineRegisterMask) == kMachineRegister; 213 return (kind & kMachineRegisterMask) == kMachineRegister;
217 } 214 }
218 215
219 static Location MachineRegisterLocation(Kind kind, 216 static Location MachineRegisterLocation(Kind kind,
220 intptr_t reg, 217 intptr_t reg) {
221 Representation rep) {
222 if (kind == kRegister) { 218 if (kind == kRegister) {
223 return RegisterLocation(static_cast<Register>(reg)); 219 return RegisterLocation(static_cast<Register>(reg));
224 } else { 220 } else {
225 ASSERT(kind == kFpuRegister); 221 ASSERT(kind == kFpuRegister);
226 return FpuRegisterLocation(static_cast<FpuRegister>(reg), rep); 222 return FpuRegisterLocation(static_cast<FpuRegister>(reg));
227 } 223 }
228 } 224 }
229 225
230 bool IsMachineRegister() const { 226 bool IsMachineRegister() const {
231 return IsMachineRegisterKind(kind()); 227 return IsMachineRegisterKind(kind());
232 } 228 }
233 229
234 intptr_t register_code() const { 230 intptr_t register_code() const {
235 ASSERT(IsMachineRegister()); 231 ASSERT(IsMachineRegister());
236 return static_cast<intptr_t>(RegisterField::decode(payload())); 232 return static_cast<intptr_t>(payload());
237 } 233 }
238 234
239 static uword make_stack_index_payload(intptr_t stack_index, 235 static uword EncodeStackIndex(intptr_t stack_index) {
240 Representation rep) {
241 ASSERT((-kStackIndexBias <= stack_index) && 236 ASSERT((-kStackIndexBias <= stack_index) &&
242 (stack_index < kStackIndexBias)); 237 (stack_index < kStackIndexBias));
243 uword payload = 238 return static_cast<uword>(kStackIndexBias + stack_index);
244 IndexField::encode(static_cast<uword>(kStackIndexBias + stack_index));
245 return payload | RepresentationField::encode(rep);
246 } 239 }
247 240
248 // Spill slots. 241 // Spill slots.
249 static Location StackSlot(intptr_t stack_index, 242 static Location StackSlot(intptr_t stack_index) {
250 Representation rep = kTagged) { 243 uword payload = EncodeStackIndex(stack_index);
251 uword payload = make_stack_index_payload(stack_index, rep);
252 Location loc(kStackSlot, payload); 244 Location loc(kStackSlot, payload);
253 // Ensure that sign is preserved. 245 // Ensure that sign is preserved.
254 ASSERT(loc.stack_index() == stack_index); 246 ASSERT(loc.stack_index() == stack_index);
255 return loc; 247 return loc;
256 } 248 }
257 249
258 bool IsStackSlot() const { 250 bool IsStackSlot() const {
259 return kind() == kStackSlot; 251 return kind() == kStackSlot;
260 } 252 }
261 253
262 static Location DoubleStackSlot(intptr_t stack_index, Representation rep) { 254 static Location DoubleStackSlot(intptr_t stack_index) {
263 uword payload = make_stack_index_payload(stack_index, rep); 255 uword payload = EncodeStackIndex(stack_index);
264 Location loc(kDoubleStackSlot, payload); 256 Location loc(kDoubleStackSlot, payload);
265 // Ensure that sign is preserved. 257 // Ensure that sign is preserved.
266 ASSERT(loc.stack_index() == stack_index); 258 ASSERT(loc.stack_index() == stack_index);
267 return loc; 259 return loc;
268 } 260 }
269 261
270 bool IsDoubleStackSlot() const { 262 bool IsDoubleStackSlot() const {
271 return kind() == kDoubleStackSlot; 263 return kind() == kDoubleStackSlot;
272 } 264 }
273 265
274 static Location Float32x4StackSlot(intptr_t stack_index) { 266 static Location QuadStackSlot(intptr_t stack_index) {
275 uword payload = make_stack_index_payload(stack_index, kUnboxedFloat32x4); 267 uword payload = EncodeStackIndex(stack_index);
276 Location loc(kFloat32x4StackSlot, payload); 268 Location loc(kQuadStackSlot, payload);
277 // Ensure that sign is preserved. 269 // Ensure that sign is preserved.
278 ASSERT(loc.stack_index() == stack_index); 270 ASSERT(loc.stack_index() == stack_index);
279 return loc; 271 return loc;
280 } 272 }
281 273
282 bool IsFloat32x4StackSlot() const { 274 bool IsQuadStackSlot() const {
283 return kind() == kFloat32x4StackSlot; 275 return kind() == kQuadStackSlot;
284 } 276 }
285 277
286 static Location Uint32x4StackSlot(intptr_t stack_index) {
287 uword payload = make_stack_index_payload(stack_index, kUnboxedUint32x4);
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
298
299 intptr_t stack_index() const { 278 intptr_t stack_index() const {
300 ASSERT(IsStackSlot() || IsDoubleStackSlot() || IsFloat32x4StackSlot() || 279 ASSERT(IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot());
301 IsUint32x4StackSlot());
302 // Decode stack index manually to preserve sign. 280 // Decode stack index manually to preserve sign.
303 return IndexField::decode(payload()) - kStackIndexBias; 281 return payload() - kStackIndexBias;
304 } 282 }
305 283
306 // Return a memory operand for stack slot locations. 284 // Return a memory operand for stack slot locations.
307 Address ToStackSlotAddress() const; 285 Address ToStackSlotAddress() const;
308 286
309 // Constants. 287 // Constants.
310 static Location RegisterOrConstant(Value* value); 288 static Location RegisterOrConstant(Value* value);
311 static Location RegisterOrSmiConstant(Value* value); 289 static Location RegisterOrSmiConstant(Value* value);
312 static Location FixedRegisterOrConstant(Value* value, Register reg); 290 static Location FixedRegisterOrConstant(Value* value, Register reg);
313 static Location FixedRegisterOrSmiConstant(Value* value, Register reg); 291 static Location FixedRegisterOrSmiConstant(Value* value, Register reg);
(...skipping 23 matching lines...) Expand all
337 uword payload() const { 315 uword payload() const {
338 return PayloadField::decode(value_); 316 return PayloadField::decode(value_);
339 } 317 }
340 318
341 typedef BitField<Kind, 0, kBitsForKind> KindField; 319 typedef BitField<Kind, 0, kBitsForKind> KindField;
342 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; 320 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField;
343 321
344 // Layout for kUnallocated locations payload. 322 // Layout for kUnallocated locations payload.
345 typedef BitField<Policy, 0, 3> PolicyField; 323 typedef BitField<Policy, 0, 3> PolicyField;
346 324
347 // Layout for register locations payload.
348 static const intptr_t kBitsForRepresentation = 3;
349 COMPILE_ASSERT(kNumRepresentations <= (1 << kBitsForRepresentation),
350 invalid_enum);
351 static const intptr_t kBitsForRegister =
352 kBitsForPayload - kBitsForRepresentation;
353 typedef BitField<Representation,
354 0,
355 kBitsForRepresentation> RepresentationField;
356 typedef BitField<Register,
357 kBitsForRepresentation,
358 kBitsForRegister> RegisterField;
359 typedef BitField<FpuRegister,
360 kBitsForRepresentation,
361 kBitsForRegister> FpuRegisterField;
362
363 // Layout for stack slots. 325 // Layout for stack slots.
364 static const intptr_t kBitsForIndex =
365 kBitsForPayload - kBitsForRepresentation;
366 typedef BitField<uword,
367 kBitsForRepresentation,
368 kBitsForIndex> IndexField;
369 static const intptr_t kStackIndexBias = 326 static const intptr_t kStackIndexBias =
370 static_cast<intptr_t>(1) << (kBitsForIndex - 1); 327 static_cast<intptr_t>(1) << (kBitsForPayload - 1);
371 328
372 // Location either contains kind and payload fields or a tagged handle for 329 // Location either contains kind and payload fields or a tagged handle for
373 // a constant locations. Values of enumeration Kind are selected in such a 330 // a constant locations. Values of enumeration Kind are selected in such a
374 // way that none of them can be interpreted as a kConstant tag. 331 // way that none of them can be interpreted as a kConstant tag.
375 uword value_; 332 uword value_;
376 }; 333 };
377 334
378 335
379 class RegisterSet : public ValueObject { 336 class RegisterSet : public ValueObject {
380 public: 337 public:
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 BitmapBuilder* stack_bitmap_; 479 BitmapBuilder* stack_bitmap_;
523 480
524 const ContainsCall contains_call_; 481 const ContainsCall contains_call_;
525 RegisterSet live_registers_; 482 RegisterSet live_registers_;
526 }; 483 };
527 484
528 485
529 } // namespace dart 486 } // namespace dart
530 487
531 #endif // VM_LOCATIONS_H_ 488 #endif // VM_LOCATIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698