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

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: 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
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
Florian Schneider 2012/08/24 11:09:28 -1 line.
181 static bool IsMachineRegisterKind(Kind kind) {
182 return (kind & kMachineRegisterMask) == kMachineRegister;
183 }
184
185 static Location MachineRegisterLocation(Kind kind, intptr_t reg) {
186 return Location(kind, reg);
187 }
188
189 bool IsMachineRegister() const {
190 return IsMachineRegisterKind(kind());
191 }
192
193 intptr_t register_code() const {
194 ASSERT(IsMachineRegister());
195 return static_cast<intptr_t>(payload());
196 }
197
153 // Spill slots. 198 // Spill slots.
154 static Location StackSlot(intptr_t stack_index) { 199 static Location StackSlot(intptr_t stack_index) {
155 ASSERT((-kStackIndexBias <= stack_index) && 200 ASSERT((-kStackIndexBias <= stack_index) &&
156 (stack_index < kStackIndexBias)); 201 (stack_index < kStackIndexBias));
157 Location loc(kStackSlot, static_cast<uword>(kStackIndexBias + stack_index)); 202 Location loc(kStackSlot, static_cast<uword>(kStackIndexBias + stack_index));
158 // Ensure that sign is preserved. 203 // Ensure that sign is preserved.
159 ASSERT(loc.stack_index() == stack_index); 204 ASSERT(loc.stack_index() == stack_index);
160 return loc; 205 return loc;
161 } 206 }
162 207
163 bool IsStackSlot() const { 208 bool IsStackSlot() const {
164 return kind() == kStackSlot; 209 return kind() == kStackSlot;
165 } 210 }
166 211
212 static Location DoubleStackSlot(intptr_t stack_index) {
213 ASSERT((-kStackIndexBias <= stack_index) &&
214 (stack_index < kStackIndexBias));
215 Location loc(kDoubleStackSlot,
216 static_cast<uword>(kStackIndexBias + stack_index));
217 // Ensure that sign is preserved.
218 ASSERT(loc.stack_index() == stack_index);
219 return loc;
220 }
221
222 bool IsDoubleStackSlot() const {
223 return kind() == kDoubleStackSlot;
224 }
225
226
167 intptr_t stack_index() const { 227 intptr_t stack_index() const {
168 ASSERT(IsStackSlot()); 228 ASSERT(IsStackSlot() || IsDoubleStackSlot());
169 // Decode stack index manually to preserve sign. 229 // Decode stack index manually to preserve sign.
170 return payload() - kStackIndexBias; 230 return payload() - kStackIndexBias;
171 } 231 }
172 232
173 const char* Name() const; 233 const char* Name() const;
174 void PrintTo(BufferFormatter* f) const; 234 void PrintTo(BufferFormatter* f) const;
175 void Print() const; 235 void Print() const;
176 236
177 // Compare two locations. 237 // Compare two locations.
178 bool Equals(Location other) const { 238 bool Equals(Location other) const {
(...skipping 13 matching lines...) Expand all
192 // If current location is constant might return something that 252 // If current location is constant might return something that
193 // is not equal to any Kind. 253 // is not equal to any Kind.
194 Kind kind() const { 254 Kind kind() const {
195 return KindField::decode(value_); 255 return KindField::decode(value_);
196 } 256 }
197 257
198 typedef BitField<Kind, 0, kBitsForKind> KindField; 258 typedef BitField<Kind, 0, kBitsForKind> KindField;
199 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField; 259 typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField;
200 260
201 // Layout for kUnallocated locations payload. 261 // Layout for kUnallocated locations payload.
202 typedef BitField<Policy, 0, 2> PolicyField; 262 typedef BitField<Policy, 0, 3> PolicyField;
203 263
204 // Location either contains kind and payload fields or a tagged handle for 264 // 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 265 // 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. 266 // way that none of them can be interpreted as a kConstant tag.
207 uword value_; 267 uword value_;
208 }; 268 };
209 269
210 270
211 class RegisterSet : public ValueObject { 271 class RegisterSet : public ValueObject {
212 public: 272 public:
213 RegisterSet() : registers_(0) { 273 RegisterSet() : cpu_registers_(0), xmm_registers_(0) {
214 ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte)); 274 ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte));
275 ASSERT(kNumberOfXmmRegisters < (kWordSize * kBitsPerByte));
215 } 276 }
216 277
217 void Add(Register reg) { 278
218 registers_ |= (1 << reg); 279 void Add(Location loc) {
280 if (loc.IsRegister()) {
281 cpu_registers_ |= (1 << loc.reg());
282 } else if (loc.IsXmmRegister()) {
283 xmm_registers_ |= (1 << loc.xmm_reg());
284 }
219 } 285 }
220 286
221 bool Contains(Register reg) { 287 void Remove(Location loc) {
222 return (registers_ & (1 << reg)) != 0; 288 if (loc.IsRegister()) {
289 cpu_registers_ &= ~(1 << loc.reg());
290 } else if (loc.IsXmmRegister()) {
291 xmm_registers_ &= ~(1 << loc.xmm_reg());
292 }
293 }
294
295 bool ContainsRegister(Register reg) {
296 return (cpu_registers_ & (1 << reg)) != 0;
297 }
298
299 bool ContainsXmmRegister(XmmRegister xmm_reg) {
300 return (xmm_registers_ & (1 << xmm_reg)) != 0;
301 }
302
303 intptr_t xmm_regs_count() {
304 intptr_t count = 0;
305 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; reg_idx++) {
306 if (ContainsXmmRegister(static_cast<XmmRegister>(reg_idx))) {
307 count++;
308 }
309 }
310 return count;
223 } 311 }
224 312
225 private: 313 private:
226 intptr_t registers_; 314 intptr_t cpu_registers_;
315 intptr_t xmm_registers_;
227 316
228 DISALLOW_COPY_AND_ASSIGN(RegisterSet); 317 DISALLOW_COPY_AND_ASSIGN(RegisterSet);
229 }; 318 };
230 319
231 320
232 // Specification of locations for inputs and output. 321 // Specification of locations for inputs and output.
233 class LocationSummary : public ZoneAllocated { 322 class LocationSummary : public ZoneAllocated {
234 public: 323 public:
235 enum ContainsCall { 324 enum ContainsCall {
236 kNoCall, 325 kNoCall,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 BitmapBuilder* stack_bitmap_; 406 BitmapBuilder* stack_bitmap_;
318 407
319 const ContainsCall contains_call_; 408 const ContainsCall contains_call_;
320 RegisterSet live_registers_; 409 RegisterSet live_registers_;
321 }; 410 };
322 411
323 412
324 } // namespace dart 413 } // namespace dart
325 414
326 #endif // VM_LOCATIONS_H_ 415 #endif // VM_LOCATIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698