| 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 |