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