| 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 |
| 193 struct ArmDoubleRegister { |
| 194 static const int kMaxNumRegisters = 16; |
| 195 // 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. |
| 197 // d14: 0.0 |
| 198 // d15: scratch register. |
| 199 static const int kNumReservedRegisters = 2; |
| 200 static const int kMaxNumAllocatableRegisters = kMaxNumRegisters - |
| 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 |
| 207 static int ToAllocationIndex(ArmDoubleRegister reg) { |
| 208 ASSERT(reg.code() != 0); |
| 209 return reg.code() - 1; |
| 210 } |
| 211 |
| 212 static ArmDoubleRegister FromAllocationIndex(int index) { |
| 213 ASSERT(index >= 0 && index < NumAllocatableRegisters()); |
| 214 return from_code(index + 1); |
| 215 } |
| 216 |
| 217 static ArmDoubleRegister from_code(int code) { |
| 218 ArmDoubleRegister r = ArmDoubleRegister(code); |
| 219 return r; |
| 220 } |
| 221 |
| 222 bool is_valid() const { |
| 223 return 0 <= code_ && code_ < NumRegisters(); |
| 224 } |
| 225 bool is(ArmDoubleRegister reg) const { return code_ == reg.code_; } |
| 226 int code() const { |
| 227 ASSERT(is_valid()); |
| 228 return code_; |
| 229 } |
| 230 |
| 231 int code_; |
| 232 }; |
| 233 |
| 234 |
| 191 // Double word VFP register. | 235 // Double word VFP register. |
| 192 struct DwVfpRegister { | 236 struct DwVfpRegister : ArmDoubleRegister { |
| 193 static const int kNumRegisters = 16; | 237 static const int kNumRegisters = 16; |
| 194 // A few double registers are reserved: one as a scratch register and one to | 238 // 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. | 239 // hold 0.0, that does not fit in the immediate field of vmov instructions. |
| 196 // d14: 0.0 | 240 // d14: 0.0 |
| 197 // d15: scratch register. | 241 // d15: scratch register. |
| 198 static const int kNumReservedRegisters = 2; | 242 static const int kNumReservedRegisters = 2; |
| 199 static const int kNumAllocatableRegisters = kNumRegisters - | 243 static const int kMaxNumAllocatableRegisters = kNumRegisters - |
| 200 kNumReservedRegisters; | 244 kNumReservedRegisters; |
| 201 | 245 |
| 202 inline static int ToAllocationIndex(DwVfpRegister reg); | 246 explicit DwVfpRegister(int code) : ArmDoubleRegister(code) {} |
| 247 |
| 248 inline int ToAllocationIndex(DwVfpRegister reg); |
| 203 | 249 |
| 204 static DwVfpRegister FromAllocationIndex(int index) { | 250 static DwVfpRegister FromAllocationIndex(int index) { |
| 205 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 251 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 206 return from_code(index); | 252 return from_code(index); |
| 207 } | 253 } |
| 208 | 254 |
| 209 static const char* AllocationIndexToString(int index) { | 255 static const char* AllocationIndexToString(int index) { |
| 210 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 256 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 211 const char* const names[] = { | 257 const char* const names[] = { |
| 212 "d0", | 258 "d0", |
| 213 "d1", | 259 "d1", |
| 214 "d2", | 260 "d2", |
| 215 "d3", | 261 "d3", |
| 216 "d4", | 262 "d4", |
| 217 "d5", | 263 "d5", |
| 218 "d6", | 264 "d6", |
| 219 "d7", | 265 "d7", |
| 220 "d8", | 266 "d8", |
| 221 "d9", | 267 "d9", |
| 222 "d10", | 268 "d10", |
| 223 "d11", | 269 "d11", |
| 224 "d12", | 270 "d12", |
| 225 "d13" | 271 "d13" |
| 226 }; | 272 }; |
| 227 return names[index]; | 273 return names[index]; |
| 228 } | 274 } |
| 229 | 275 |
| 230 static DwVfpRegister from_code(int code) { | 276 static DwVfpRegister from_code(int code) { |
| 231 DwVfpRegister r = { code }; | 277 DwVfpRegister r = DwVfpRegister(code); |
| 232 return r; | 278 return r; |
| 233 } | 279 } |
| 234 | 280 |
| 235 // Supporting d0 to d15, can be later extended to d31. | 281 // Supporting d0 to d15, can be later extended to d31. |
| 236 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 282 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
| 237 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } | 283 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } |
| 238 SwVfpRegister low() const { | 284 SwVfpRegister low() const { |
| 239 SwVfpRegister reg; | 285 SwVfpRegister reg; |
| 240 reg.code_ = code_ * 2; | 286 reg.code_ = code_ * 2; |
| 241 | 287 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 255 } | 301 } |
| 256 int bit() const { | 302 int bit() const { |
| 257 ASSERT(is_valid()); | 303 ASSERT(is_valid()); |
| 258 return 1 << code_; | 304 return 1 << code_; |
| 259 } | 305 } |
| 260 void split_code(int* vm, int* m) const { | 306 void split_code(int* vm, int* m) const { |
| 261 ASSERT(is_valid()); | 307 ASSERT(is_valid()); |
| 262 *m = (code_ & 0x10) >> 4; | 308 *m = (code_ & 0x10) >> 4; |
| 263 *vm = code_ & 0x0F; | 309 *vm = code_ & 0x0F; |
| 264 } | 310 } |
| 265 | |
| 266 int code_; | |
| 267 }; | 311 }; |
| 268 | 312 |
| 269 | 313 |
| 270 typedef DwVfpRegister DoubleRegister; | 314 // Double word VFP register. |
| 315 struct SoftFloatRegister : ArmDoubleRegister { |
| 316 static const int kNumRegisters = 1; |
| 317 static const int kMaxNumAllocatableRegisters = kNumRegisters; |
| 318 |
| 319 explicit SoftFloatRegister(int code) : ArmDoubleRegister(code) {} |
| 320 |
| 321 static SoftFloatRegister FromAllocationIndex(int index) { |
| 322 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 323 return from_code(index); |
| 324 } |
| 325 |
| 326 static const char* AllocationIndexToString(int index) { |
| 327 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 328 const char* const names[] = { |
| 329 "sfpd0" |
| 330 }; |
| 331 return names[index]; |
| 332 } |
| 333 |
| 334 static SoftFloatRegister from_code(int code) { |
| 335 SoftFloatRegister r = SoftFloatRegister(code); |
| 336 return r; |
| 337 } |
| 338 }; |
| 339 |
| 340 |
| 341 typedef ArmDoubleRegister DoubleRegister; |
| 271 | 342 |
| 272 | 343 |
| 273 // Support for the VFP registers s0 to s31 (d0 to d15). | 344 // 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)". | 345 // Note that "s(N):s(N+1)" is the same as "d(N/2)". |
| 275 const SwVfpRegister s0 = { 0 }; | 346 const SwVfpRegister s0 = { 0 }; |
| 276 const SwVfpRegister s1 = { 1 }; | 347 const SwVfpRegister s1 = { 1 }; |
| 277 const SwVfpRegister s2 = { 2 }; | 348 const SwVfpRegister s2 = { 2 }; |
| 278 const SwVfpRegister s3 = { 3 }; | 349 const SwVfpRegister s3 = { 3 }; |
| 279 const SwVfpRegister s4 = { 4 }; | 350 const SwVfpRegister s4 = { 4 }; |
| 280 const SwVfpRegister s5 = { 5 }; | 351 const SwVfpRegister s5 = { 5 }; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 298 const SwVfpRegister s23 = { 23 }; | 369 const SwVfpRegister s23 = { 23 }; |
| 299 const SwVfpRegister s24 = { 24 }; | 370 const SwVfpRegister s24 = { 24 }; |
| 300 const SwVfpRegister s25 = { 25 }; | 371 const SwVfpRegister s25 = { 25 }; |
| 301 const SwVfpRegister s26 = { 26 }; | 372 const SwVfpRegister s26 = { 26 }; |
| 302 const SwVfpRegister s27 = { 27 }; | 373 const SwVfpRegister s27 = { 27 }; |
| 303 const SwVfpRegister s28 = { 28 }; | 374 const SwVfpRegister s28 = { 28 }; |
| 304 const SwVfpRegister s29 = { 29 }; | 375 const SwVfpRegister s29 = { 29 }; |
| 305 const SwVfpRegister s30 = { 30 }; | 376 const SwVfpRegister s30 = { 30 }; |
| 306 const SwVfpRegister s31 = { 31 }; | 377 const SwVfpRegister s31 = { 31 }; |
| 307 | 378 |
| 308 const DwVfpRegister no_dreg = { -1 }; | 379 const DwVfpRegister no_dreg = DwVfpRegister(-1); |
| 309 const DwVfpRegister d0 = { 0 }; | 380 const DwVfpRegister d0 = DwVfpRegister(0); |
| 310 const DwVfpRegister d1 = { 1 }; | 381 const DwVfpRegister d1 = DwVfpRegister(1); |
| 311 const DwVfpRegister d2 = { 2 }; | 382 const DwVfpRegister d2 = DwVfpRegister(2); |
| 312 const DwVfpRegister d3 = { 3 }; | 383 const DwVfpRegister d3 = DwVfpRegister(3); |
| 313 const DwVfpRegister d4 = { 4 }; | 384 const DwVfpRegister d4 = DwVfpRegister(4); |
| 314 const DwVfpRegister d5 = { 5 }; | 385 const DwVfpRegister d5 = DwVfpRegister(5); |
| 315 const DwVfpRegister d6 = { 6 }; | 386 const DwVfpRegister d6 = DwVfpRegister(6); |
| 316 const DwVfpRegister d7 = { 7 }; | 387 const DwVfpRegister d7 = DwVfpRegister(7); |
| 317 const DwVfpRegister d8 = { 8 }; | 388 const DwVfpRegister d8 = DwVfpRegister(8); |
| 318 const DwVfpRegister d9 = { 9 }; | 389 const DwVfpRegister d9 = DwVfpRegister(9); |
| 319 const DwVfpRegister d10 = { 10 }; | 390 const DwVfpRegister d10 = DwVfpRegister(10); |
| 320 const DwVfpRegister d11 = { 11 }; | 391 const DwVfpRegister d11 = DwVfpRegister(11); |
| 321 const DwVfpRegister d12 = { 12 }; | 392 const DwVfpRegister d12 = DwVfpRegister(12); |
| 322 const DwVfpRegister d13 = { 13 }; | 393 const DwVfpRegister d13 = DwVfpRegister(13); |
| 323 const DwVfpRegister d14 = { 14 }; | 394 const DwVfpRegister d14 = DwVfpRegister(14); |
| 324 const DwVfpRegister d15 = { 15 }; | 395 const DwVfpRegister d15 = DwVfpRegister(15); |
| 396 |
| 397 const Register sfpd_lo = { kRegister_r6_Code }; |
| 398 const Register sfpd_hi = { kRegister_r7_Code }; |
| 325 | 399 |
| 326 // Aliases for double registers. Defined using #define instead of | 400 // Aliases for double registers. Defined using #define instead of |
| 327 // "static const DwVfpRegister&" because Clang complains otherwise when a | 401 // "static const DwVfpRegister&" because Clang complains otherwise when a |
| 328 // compilation unit that includes this header doesn't use the variables. | 402 // compilation unit that includes this header doesn't use the variables. |
| 329 #define kFirstCalleeSavedDoubleReg d8 | 403 #define kFirstCalleeSavedDoubleReg d8 |
| 330 #define kLastCalleeSavedDoubleReg d15 | 404 #define kLastCalleeSavedDoubleReg d15 |
| 331 #define kDoubleRegZero d14 | 405 #define kDoubleRegZero d14 |
| 332 #define kScratchDoubleReg d15 | 406 #define kScratchDoubleReg d15 |
| 333 | 407 |
| 334 | 408 |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 public: | 1572 public: |
| 1499 explicit EnsureSpace(Assembler* assembler) { | 1573 explicit EnsureSpace(Assembler* assembler) { |
| 1500 assembler->CheckBuffer(); | 1574 assembler->CheckBuffer(); |
| 1501 } | 1575 } |
| 1502 }; | 1576 }; |
| 1503 | 1577 |
| 1504 | 1578 |
| 1505 } } // namespace v8::internal | 1579 } } // namespace v8::internal |
| 1506 | 1580 |
| 1507 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1581 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |