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

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

Issue 10875030: Add support for XMM registers in SSA code generation pipeline. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix a bug pointed out by Florian Created 8 years, 4 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
« no previous file with comments | « runtime/vm/intrinsifier_x64.cc ('k') | runtime/vm/locations.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 17 matching lines...) Expand all
28 // Number of bits required to encode Kind value. 28 // Number of bits required to encode Kind value.
29 kBitsForKind = 3, 29 kBitsForKind = 3,
30 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind, 30 kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind,
31 }; 31 };
32 32
33 static const uword kInvalidLocation = 0; 33 static const uword kInvalidLocation = 0;
34 static const uword kConstantMask = 0x3; 34 static const uword kConstantMask = 0x3;
35 static const intptr_t kStackIndexBias = 35 static const intptr_t kStackIndexBias =
36 static_cast<intptr_t>(1) << (kBitsForPayload - 1); 36 static_cast<intptr_t>(1) << (kBitsForPayload - 1);
37 37
38 static const intptr_t kMachineRegisterMask = 0x6;
39 static const intptr_t kMachineRegister = 0x6;
40
38 public: 41 public:
39 // Constant payload can overlap with kind field so Kind values 42 // Constant payload can overlap with kind field so Kind values
40 // have to be chosen in a way that their last 2 bits are never 43 // have to be chosen in a way that their last 2 bits are never
41 // the same as kConstant. 44 // the same as kConstant.
42 enum Kind { 45 enum Kind {
43 // This location is invalid. Payload must be zero. 46 // This location is invalid. Payload must be zero.
44 kInvalid = 0, 47 kInvalid = 0,
45 48
46 // Constant value. This location contains a tagged Object handle. 49 // Constant value. This location contains a tagged Object handle.
47 kConstant = 1, 50 kConstant = 1,
48 51
49 // Unallocated location represents a location that is not fixed and can be 52 // Unallocated location represents a location that is not fixed and can be
50 // allocated by a register allocator. Each unallocated location has 53 // allocated by a register allocator. Each unallocated location has
51 // a policy that specifies what kind of location is suitable. Payload 54 // a policy that specifies what kind of location is suitable. Payload
52 // contains register allocation policy. 55 // contains register allocation policy.
53 kUnallocated = 2, 56 kUnallocated = 2,
54 57
58 // Spill slot allocated by the register allocator. Payload contains
59 // a spill index.
60 kStackSlot = 3,
61 kDoubleStackSlot = 4,
62
55 // Register location represents a fixed register. Payload contains 63 // Register location represents a fixed register. Payload contains
56 // register code. 64 // register code.
57 kRegister = 3, 65 kRegister = 6,
58 66
59 // Spill slot allocated by the register allocator. Payload contains 67 // XmmRegister location represents a fixed xmm register. Payload contains
60 // a spill index. 68 // its code.
61 kStackSlot = 4, 69 kXmmRegister = 7,
62 }; 70 };
63 71
64 Location() : value_(kInvalidLocation) { 72 Location() : value_(kInvalidLocation) {
65 ASSERT(IsInvalid()); 73 ASSERT(IsInvalid());
66 } 74 }
67 75
68 bool IsInvalid() const { 76 bool IsInvalid() const {
69 return value_ == kInvalidLocation; 77 return value_ == kInvalidLocation;
70 } 78 }
71 79
(...skipping 13 matching lines...) Expand all
85 ASSERT(IsConstant()); 93 ASSERT(IsConstant());
86 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask); 94 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask);
87 } 95 }
88 96
89 // Unallocated locations. 97 // Unallocated locations.
90 // TODO(vegorov): writable register policy? 98 // TODO(vegorov): writable register policy?
91 enum Policy { 99 enum Policy {
92 kAny, 100 kAny,
93 kPrefersRegister, 101 kPrefersRegister,
94 kRequiresRegister, 102 kRequiresRegister,
103 kRequiresXmmRegister,
95 kSameAsFirstInput, 104 kSameAsFirstInput,
96 }; 105 };
97 106
98 bool IsUnallocated() const { 107 bool IsUnallocated() const {
99 return kind() == kUnallocated; 108 return kind() == kUnallocated;
100 } 109 }
101 110
102 bool IsRegisterBeneficial() { 111 bool IsRegisterBeneficial() {
103 return !Equals(Any()); 112 return !Equals(Any());
104 } 113 }
105 114
106 static Location UnallocatedLocation(Policy policy) { 115 static Location UnallocatedLocation(Policy policy) {
107 return Location(kUnallocated, PolicyField::encode(policy)); 116 return Location(kUnallocated, PolicyField::encode(policy));
108 } 117 }
109 118
110 // Any free register is suitable to replace this unallocated location. 119 // Any free register is suitable to replace this unallocated location.
111 static Location Any() { 120 static Location Any() {
112 return UnallocatedLocation(kAny); 121 return UnallocatedLocation(kAny);
113 } 122 }
114 123
115 static Location PrefersRegister() { 124 static Location PrefersRegister() {
116 return UnallocatedLocation(kPrefersRegister); 125 return UnallocatedLocation(kPrefersRegister);
117 } 126 }
118 127
119 static Location RequiresRegister() { 128 static Location RequiresRegister() {
120 return UnallocatedLocation(kRequiresRegister); 129 return UnallocatedLocation(kRequiresRegister);
121 } 130 }
122 131
132 static Location RequiresXmmRegister() {
133 return UnallocatedLocation(kRequiresXmmRegister);
134 }
135
123 // The location of the first input to the instruction will be 136 // The location of the first input to the instruction will be
124 // used to replace this unallocated location. 137 // used to replace this unallocated location.
125 static Location SameAsFirstInput() { 138 static Location SameAsFirstInput() {
126 return UnallocatedLocation(kSameAsFirstInput); 139 return UnallocatedLocation(kSameAsFirstInput);
127 } 140 }
128 141
129 // Empty location. Used if there the location should be ignored. 142 // Empty location. Used if there the location should be ignored.
130 static Location NoLocation() { 143 static Location NoLocation() {
131 return Location(); 144 return Location();
132 } 145 }
(...skipping 10 matching lines...) Expand all
143 156
144 bool IsRegister() const { 157 bool IsRegister() const {
145 return kind() == kRegister; 158 return kind() == kRegister;
146 } 159 }
147 160
148 Register reg() const { 161 Register reg() const {
149 ASSERT(IsRegister()); 162 ASSERT(IsRegister());
150 return static_cast<Register>(payload()); 163 return static_cast<Register>(payload());
151 } 164 }
152 165
166 // XmmRegister locations.
167 static Location XmmRegisterLocation(XmmRegister reg) {
168 return Location(kXmmRegister, static_cast<uword>(reg));
169 }
170
171 bool IsXmmRegister() const {
172 return kind() == kXmmRegister;
173 }
174
175 XmmRegister xmm_reg() const {
176 ASSERT(IsXmmRegister());
177 return static_cast<XmmRegister>(payload());
178 }
179
180 static bool IsMachineRegisterKind(Kind kind) {
181 return (kind & kMachineRegisterMask) == kMachineRegister;
182 }
183
184 static Location MachineRegisterLocation(Kind kind, intptr_t reg) {
185 return Location(kind, reg);
186 }
187
188 bool IsMachineRegister() const {
189 return IsMachineRegisterKind(kind());
190 }
191
192 intptr_t register_code() const {
193 ASSERT(IsMachineRegister());
194 return static_cast<intptr_t>(payload());
195 }
196
153 // Spill slots. 197 // Spill slots.
154 static Location StackSlot(intptr_t stack_index) { 198 static Location StackSlot(intptr_t stack_index) {
155 ASSERT((-kStackIndexBias <= stack_index) && 199 ASSERT((-kStackIndexBias <= stack_index) &&
156 (stack_index < kStackIndexBias)); 200 (stack_index < kStackIndexBias));
157 Location loc(kStackSlot, static_cast<uword>(kStackIndexBias + stack_index)); 201 Location loc(kStackSlot, static_cast<uword>(kStackIndexBias + stack_index));
158 // Ensure that sign is preserved. 202 // Ensure that sign is preserved.
159 ASSERT(loc.stack_index() == stack_index); 203 ASSERT(loc.stack_index() == stack_index);
160 return loc; 204 return loc;
161 } 205 }
162 206
163 bool IsStackSlot() const { 207 bool IsStackSlot() const {
164 return kind() == kStackSlot; 208 return kind() == kStackSlot;
165 } 209 }
166 210
211 static Location DoubleStackSlot(intptr_t stack_index) {
212 ASSERT((-kStackIndexBias <= stack_index) &&
213 (stack_index < kStackIndexBias));
214 Location loc(kDoubleStackSlot,
215 static_cast<uword>(kStackIndexBias + stack_index));
216 // Ensure that sign is preserved.
217 ASSERT(loc.stack_index() == stack_index);
218 return loc;
219 }
220
221 bool IsDoubleStackSlot() const {
222 return kind() == kDoubleStackSlot;
223 }
224
225
167 intptr_t stack_index() const { 226 intptr_t stack_index() const {
168 ASSERT(IsStackSlot()); 227 ASSERT(IsStackSlot() || IsDoubleStackSlot());
169 // Decode stack index manually to preserve sign. 228 // Decode stack index manually to preserve sign.
170 return payload() - kStackIndexBias; 229 return payload() - kStackIndexBias;
171 } 230 }
172 231
173 const char* Name() const; 232 const char* Name() const;
174 void PrintTo(BufferFormatter* f) const; 233 void PrintTo(BufferFormatter* f) const;
175 void Print() const; 234 void Print() const;
176 235
177 // Compare two locations. 236 // Compare two locations.
178 bool Equals(Location other) const { 237 bool Equals(Location other) const {
(...skipping 13 matching lines...) Expand all
192 // If current location is constant might return something that 251 // If current location is constant might return something that
193 // is not equal to any Kind. 252 // is not equal to any Kind.
194 Kind kind() const { 253 Kind kind() const {
195 return KindField::decode(value_); 254 return KindField::decode(value_);
196 } 255 }
197 256
198 typedef BitField<Kind, 0, kBitsForKind> KindField; 257 typedef BitField<Kind, 0, kBitsForKind> KindField;
199 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; 258 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField;
200 259
201 // Layout for kUnallocated locations payload. 260 // Layout for kUnallocated locations payload.
202 typedef BitField<Policy, 0, 2> PolicyField; 261 typedef BitField<Policy, 0, 3> PolicyField;
203 262
204 // Location either contains kind and payload fields or a tagged handle for 263 // Location either contains kind and payload fields or a tagged handle for
205 // a constant locations. Values of enumeration Kind are selected in such a 264 // a constant locations. Values of enumeration Kind are selected in such a
206 // way that none of them can be interpreted as a kConstant tag. 265 // way that none of them can be interpreted as a kConstant tag.
207 uword value_; 266 uword value_;
208 }; 267 };
209 268
210 269
211 class RegisterSet : public ValueObject { 270 class RegisterSet : public ValueObject {
212 public: 271 public:
213 RegisterSet() : registers_(0) { 272 RegisterSet() : cpu_registers_(0), xmm_registers_(0) {
214 ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte)); 273 ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte));
274 ASSERT(kNumberOfXmmRegisters < (kWordSize * kBitsPerByte));
215 } 275 }
216 276
217 void Add(Register reg) { 277
218 registers_ |= (1 << reg); 278 void Add(Location loc) {
279 if (loc.IsRegister()) {
280 cpu_registers_ |= (1 << loc.reg());
281 } else if (loc.IsXmmRegister()) {
282 xmm_registers_ |= (1 << loc.xmm_reg());
283 }
219 } 284 }
220 285
221 bool Contains(Register reg) { 286 void Remove(Location loc) {
222 return (registers_ & (1 << reg)) != 0; 287 if (loc.IsRegister()) {
288 cpu_registers_ &= ~(1 << loc.reg());
289 } else if (loc.IsXmmRegister()) {
290 xmm_registers_ &= ~(1 << loc.xmm_reg());
291 }
292 }
293
294 bool ContainsRegister(Register reg) {
295 return (cpu_registers_ & (1 << reg)) != 0;
296 }
297
298 bool ContainsXmmRegister(XmmRegister xmm_reg) {
299 return (xmm_registers_ & (1 << xmm_reg)) != 0;
300 }
301
302 intptr_t xmm_regs_count() {
303 intptr_t count = 0;
304 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; reg_idx++) {
305 if (ContainsXmmRegister(static_cast<XmmRegister>(reg_idx))) {
306 count++;
307 }
308 }
309 return count;
223 } 310 }
224 311
225 private: 312 private:
226 intptr_t registers_; 313 intptr_t cpu_registers_;
314 intptr_t xmm_registers_;
227 315
228 DISALLOW_COPY_AND_ASSIGN(RegisterSet); 316 DISALLOW_COPY_AND_ASSIGN(RegisterSet);
229 }; 317 };
230 318
231 319
232 // Specification of locations for inputs and output. 320 // Specification of locations for inputs and output.
233 class LocationSummary : public ZoneAllocated { 321 class LocationSummary : public ZoneAllocated {
234 public: 322 public:
235 enum ContainsCall { 323 enum ContainsCall {
236 kNoCall, 324 kNoCall,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 BitmapBuilder* stack_bitmap_; 405 BitmapBuilder* stack_bitmap_;
318 406
319 const ContainsCall contains_call_; 407 const ContainsCall contains_call_;
320 RegisterSet live_registers_; 408 RegisterSet live_registers_;
321 }; 409 };
322 410
323 411
324 } // namespace dart 412 } // namespace dart
325 413
326 #endif // VM_LOCATIONS_H_ 414 #endif // VM_LOCATIONS_H_
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_x64.cc ('k') | runtime/vm/locations.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698