OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 // doing certain constant folds, which may significantly reduce the | 64 // doing certain constant folds, which may significantly reduce the |
65 // code generated for some assembly instructions (because they boil down | 65 // code generated for some assembly instructions (because they boil down |
66 // to a few constants). If this is a problem, we could change the code | 66 // to a few constants). If this is a problem, we could change the code |
67 // such that we use an enum in optimized mode, and the struct in debug | 67 // such that we use an enum in optimized mode, and the struct in debug |
68 // mode. This way we get the compile-time error checking in debug mode | 68 // mode. This way we get the compile-time error checking in debug mode |
69 // and best performance in optimized code. | 69 // and best performance in optimized code. |
70 | 70 |
71 // Core register | 71 // Core register |
72 struct Register { | 72 struct Register { |
73 static const int kNumRegisters = 16; | 73 static const int kNumRegisters = 16; |
74 static const int kMaxNumAllocatableRegisters = 8; | 74 static const int kNumAllocatableRegisters = 8; |
75 static const int kGPRsPerNonVFP2Double = 2; | |
76 static int NumAllocatableRegisters(); | |
77 static const int kSizeInBytes = 4; | 75 static const int kSizeInBytes = 4; |
78 | 76 |
79 static int ToAllocationIndex(Register reg) { | 77 static int ToAllocationIndex(Register reg) { |
80 ASSERT(reg.code() < NumAllocatableRegisters()); | 78 ASSERT(reg.code() < kNumAllocatableRegisters); |
81 return reg.code(); | 79 return reg.code(); |
82 } | 80 } |
83 | 81 |
84 static Register FromAllocationIndex(int index) { | 82 static Register FromAllocationIndex(int index) { |
85 ASSERT(index >= 0 && index < NumAllocatableRegisters()); | 83 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
86 return from_code(index); | 84 return from_code(index); |
87 } | 85 } |
88 | 86 |
89 static const char* AllocationIndexToString(int index) { | 87 static const char* AllocationIndexToString(int index) { |
90 ASSERT(index >= 0 && index < NumAllocatableRegisters()); | 88 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
91 const char* const names[] = { | 89 const char* const names[] = { |
92 "r0", | 90 "r0", |
93 "r1", | 91 "r1", |
94 "r2", | 92 "r2", |
95 "r3", | 93 "r3", |
96 "r4", | 94 "r4", |
97 "r5", | 95 "r5", |
98 "r6", | 96 "r6", |
99 "r7", | 97 "r7", |
100 }; | 98 }; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 void split_code(int* vm, int* m) const { | 181 void split_code(int* vm, int* m) const { |
184 ASSERT(is_valid()); | 182 ASSERT(is_valid()); |
185 *m = code_ & 0x1; | 183 *m = code_ & 0x1; |
186 *vm = code_ >> 1; | 184 *vm = code_ >> 1; |
187 } | 185 } |
188 | 186 |
189 int code_; | 187 int code_; |
190 }; | 188 }; |
191 | 189 |
192 | 190 |
193 struct ArmDoubleRegister { | 191 // Double word VFP register. |
194 static const int kMaxNumRegisters = 16; | 192 struct DwVfpRegister { |
| 193 static const int kNumRegisters = 16; |
195 // A few double registers are reserved: one as a scratch register and one to | 194 // A few double registers are reserved: one as a scratch register and one to |
196 // hold 0.0, that does not fit in the immediate field of vmov instructions. | 195 // hold 0.0, that does not fit in the immediate field of vmov instructions. |
197 // d14: 0.0 | 196 // d14: 0.0 |
198 // d15: scratch register. | 197 // d15: scratch register. |
199 static const int kNumReservedRegisters = 2; | 198 static const int kNumReservedRegisters = 2; |
200 static const int kMaxNumAllocatableRegisters = kMaxNumRegisters - | 199 static const int kNumAllocatableRegisters = kNumRegisters - |
201 kNumReservedRegisters; | 200 kNumReservedRegisters; |
202 explicit ArmDoubleRegister(int code) { code_ = code; } | |
203 static int NumAllocatableRegisters(); | |
204 static int NumRegisters() { return kNumRegisters; } | |
205 static const char* AllocationIndexToString(int index); | |
206 inline static ArmDoubleRegister FromAllocationIndex(int index); | |
207 inline static int ToAllocationIndex(ArmDoubleRegister reg) { | |
208 return reg.code(); | |
209 } | |
210 | 201 |
211 static ArmDoubleRegister from_code(int code) { | 202 inline static int ToAllocationIndex(DwVfpRegister reg); |
212 ArmDoubleRegister r = ArmDoubleRegister(code); | |
213 return r; | |
214 } | |
215 | |
216 bool is_valid() const { | |
217 return 0 <= code_ && code_ < NumRegisters(); | |
218 } | |
219 bool is(ArmDoubleRegister reg) const { return code_ == reg.code_; } | |
220 int code() const { | |
221 ASSERT(is_valid()); | |
222 return code_; | |
223 } | |
224 | |
225 int code_; | |
226 }; | |
227 | |
228 | |
229 // Double word VFP register. | |
230 struct DwVfpRegister : ArmDoubleRegister { | |
231 static const int kNumRegisters = 16; | |
232 | |
233 explicit DwVfpRegister(int code) : ArmDoubleRegister(code) {} | |
234 | |
235 inline int ToAllocationIndex(DwVfpRegister reg); | |
236 | 203 |
237 static DwVfpRegister FromAllocationIndex(int index) { | 204 static DwVfpRegister FromAllocationIndex(int index) { |
238 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 205 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
239 return from_code(index); | 206 return from_code(index); |
240 } | 207 } |
241 | 208 |
242 static const char* AllocationIndexToString(int index) { | 209 static const char* AllocationIndexToString(int index) { |
243 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 210 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
244 const char* const names[] = { | 211 const char* const names[] = { |
245 "d0", | 212 "d0", |
246 "d1", | 213 "d1", |
247 "d2", | 214 "d2", |
248 "d3", | 215 "d3", |
249 "d4", | 216 "d4", |
250 "d5", | 217 "d5", |
251 "d6", | 218 "d6", |
252 "d7", | 219 "d7", |
253 "d8", | 220 "d8", |
254 "d9", | 221 "d9", |
255 "d10", | 222 "d10", |
256 "d11", | 223 "d11", |
257 "d12", | 224 "d12", |
258 "d13" | 225 "d13" |
259 }; | 226 }; |
260 return names[index]; | 227 return names[index]; |
261 } | 228 } |
262 | 229 |
263 static DwVfpRegister from_code(int code) { | 230 static DwVfpRegister from_code(int code) { |
264 return DwVfpRegister(code); | 231 DwVfpRegister r = { code }; |
| 232 return r; |
265 } | 233 } |
266 | 234 |
267 // Supporting d0 to d15, can be later extended to d31. | 235 // Supporting d0 to d15, can be later extended to d31. |
268 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 236 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
269 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } | 237 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } |
270 SwVfpRegister low() const { | 238 SwVfpRegister low() const { |
271 SwVfpRegister reg; | 239 SwVfpRegister reg; |
272 reg.code_ = code_ * 2; | 240 reg.code_ = code_ * 2; |
273 | 241 |
274 ASSERT(reg.is_valid()); | 242 ASSERT(reg.is_valid()); |
(...skipping 12 matching lines...) Expand all Loading... |
287 } | 255 } |
288 int bit() const { | 256 int bit() const { |
289 ASSERT(is_valid()); | 257 ASSERT(is_valid()); |
290 return 1 << code_; | 258 return 1 << code_; |
291 } | 259 } |
292 void split_code(int* vm, int* m) const { | 260 void split_code(int* vm, int* m) const { |
293 ASSERT(is_valid()); | 261 ASSERT(is_valid()); |
294 *m = (code_ & 0x10) >> 4; | 262 *m = (code_ & 0x10) >> 4; |
295 *vm = code_ & 0x0F; | 263 *vm = code_ & 0x0F; |
296 } | 264 } |
| 265 |
| 266 int code_; |
297 }; | 267 }; |
298 | 268 |
299 | 269 |
300 // Double word VFP register. | 270 typedef DwVfpRegister DoubleRegister; |
301 struct SoftFloatRegister : ArmDoubleRegister { | |
302 static const int kNumRegisters = 1; | |
303 static const int kMaxNumAllocatableRegisters = kNumRegisters; | |
304 | |
305 explicit SoftFloatRegister(int code) : ArmDoubleRegister(code) {} | |
306 | |
307 static SoftFloatRegister FromAllocationIndex(int index) { | |
308 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | |
309 return from_code(index); | |
310 } | |
311 | |
312 static const char* AllocationIndexToString(int index) { | |
313 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | |
314 const char* const names[] = { | |
315 "sfpd0" | |
316 }; | |
317 return names[index]; | |
318 } | |
319 | |
320 static SoftFloatRegister from_code(int code) { | |
321 SoftFloatRegister r = SoftFloatRegister(code); | |
322 return r; | |
323 } | |
324 }; | |
325 | |
326 | |
327 typedef ArmDoubleRegister DoubleRegister; | |
328 | 271 |
329 | 272 |
330 // Support for the VFP registers s0 to s31 (d0 to d15). | 273 // Support for the VFP registers s0 to s31 (d0 to d15). |
331 // Note that "s(N):s(N+1)" is the same as "d(N/2)". | 274 // Note that "s(N):s(N+1)" is the same as "d(N/2)". |
332 const SwVfpRegister s0 = { 0 }; | 275 const SwVfpRegister s0 = { 0 }; |
333 const SwVfpRegister s1 = { 1 }; | 276 const SwVfpRegister s1 = { 1 }; |
334 const SwVfpRegister s2 = { 2 }; | 277 const SwVfpRegister s2 = { 2 }; |
335 const SwVfpRegister s3 = { 3 }; | 278 const SwVfpRegister s3 = { 3 }; |
336 const SwVfpRegister s4 = { 4 }; | 279 const SwVfpRegister s4 = { 4 }; |
337 const SwVfpRegister s5 = { 5 }; | 280 const SwVfpRegister s5 = { 5 }; |
(...skipping 17 matching lines...) Expand all Loading... |
355 const SwVfpRegister s23 = { 23 }; | 298 const SwVfpRegister s23 = { 23 }; |
356 const SwVfpRegister s24 = { 24 }; | 299 const SwVfpRegister s24 = { 24 }; |
357 const SwVfpRegister s25 = { 25 }; | 300 const SwVfpRegister s25 = { 25 }; |
358 const SwVfpRegister s26 = { 26 }; | 301 const SwVfpRegister s26 = { 26 }; |
359 const SwVfpRegister s27 = { 27 }; | 302 const SwVfpRegister s27 = { 27 }; |
360 const SwVfpRegister s28 = { 28 }; | 303 const SwVfpRegister s28 = { 28 }; |
361 const SwVfpRegister s29 = { 29 }; | 304 const SwVfpRegister s29 = { 29 }; |
362 const SwVfpRegister s30 = { 30 }; | 305 const SwVfpRegister s30 = { 30 }; |
363 const SwVfpRegister s31 = { 31 }; | 306 const SwVfpRegister s31 = { 31 }; |
364 | 307 |
365 const DwVfpRegister no_dreg = DwVfpRegister(-1); | 308 const DwVfpRegister no_dreg = { -1 }; |
366 const DwVfpRegister d0 = DwVfpRegister(0); | 309 const DwVfpRegister d0 = { 0 }; |
367 const DwVfpRegister d1 = DwVfpRegister(1); | 310 const DwVfpRegister d1 = { 1 }; |
368 const DwVfpRegister d2 = DwVfpRegister(2); | 311 const DwVfpRegister d2 = { 2 }; |
369 const DwVfpRegister d3 = DwVfpRegister(3); | 312 const DwVfpRegister d3 = { 3 }; |
370 const DwVfpRegister d4 = DwVfpRegister(4); | 313 const DwVfpRegister d4 = { 4 }; |
371 const DwVfpRegister d5 = DwVfpRegister(5); | 314 const DwVfpRegister d5 = { 5 }; |
372 const DwVfpRegister d6 = DwVfpRegister(6); | 315 const DwVfpRegister d6 = { 6 }; |
373 const DwVfpRegister d7 = DwVfpRegister(7); | 316 const DwVfpRegister d7 = { 7 }; |
374 const DwVfpRegister d8 = DwVfpRegister(8); | 317 const DwVfpRegister d8 = { 8 }; |
375 const DwVfpRegister d9 = DwVfpRegister(9); | 318 const DwVfpRegister d9 = { 9 }; |
376 const DwVfpRegister d10 = DwVfpRegister(10); | 319 const DwVfpRegister d10 = { 10 }; |
377 const DwVfpRegister d11 = DwVfpRegister(11); | 320 const DwVfpRegister d11 = { 11 }; |
378 const DwVfpRegister d12 = DwVfpRegister(12); | 321 const DwVfpRegister d12 = { 12 }; |
379 const DwVfpRegister d13 = DwVfpRegister(13); | 322 const DwVfpRegister d13 = { 13 }; |
380 const DwVfpRegister d14 = DwVfpRegister(14); | 323 const DwVfpRegister d14 = { 14 }; |
381 const DwVfpRegister d15 = DwVfpRegister(15); | 324 const DwVfpRegister d15 = { 15 }; |
382 | |
383 const Register sfpd_lo = { kRegister_r6_Code }; | |
384 const Register sfpd_hi = { kRegister_r7_Code }; | |
385 | 325 |
386 // Aliases for double registers. Defined using #define instead of | 326 // Aliases for double registers. Defined using #define instead of |
387 // "static const DwVfpRegister&" because Clang complains otherwise when a | 327 // "static const DwVfpRegister&" because Clang complains otherwise when a |
388 // compilation unit that includes this header doesn't use the variables. | 328 // compilation unit that includes this header doesn't use the variables. |
389 #define kFirstCalleeSavedDoubleReg d8 | 329 #define kFirstCalleeSavedDoubleReg d8 |
390 #define kLastCalleeSavedDoubleReg d15 | 330 #define kLastCalleeSavedDoubleReg d15 |
391 #define kDoubleRegZero d14 | 331 #define kDoubleRegZero d14 |
392 #define kScratchDoubleReg d15 | 332 #define kScratchDoubleReg d15 |
393 | 333 |
394 | 334 |
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 public: | 1488 public: |
1549 explicit EnsureSpace(Assembler* assembler) { | 1489 explicit EnsureSpace(Assembler* assembler) { |
1550 assembler->CheckBuffer(); | 1490 assembler->CheckBuffer(); |
1551 } | 1491 } |
1552 }; | 1492 }; |
1553 | 1493 |
1554 | 1494 |
1555 } } // namespace v8::internal | 1495 } } // namespace v8::internal |
1556 | 1496 |
1557 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1497 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |