Chromium Code Reviews| 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 DwVfpRegister r = DwVfpRegister(code); |
|
Jakob Kummerow
2012/11/28 16:28:22
nit: how about just:
return DwVfpRegister(code);
danno
2012/11/30 16:23:24
Done.
| |
| 232 return r; | 265 return r; |
| 233 } | 266 } |
| 234 | 267 |
| 235 // Supporting d0 to d15, can be later extended to d31. | 268 // Supporting d0 to d15, can be later extended to d31. |
| 236 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 269 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
| 237 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } | 270 bool is(DwVfpRegister reg) const { return code_ == reg.code_; } |
| 238 SwVfpRegister low() const { | 271 SwVfpRegister low() const { |
| 239 SwVfpRegister reg; | 272 SwVfpRegister reg; |
| 240 reg.code_ = code_ * 2; | 273 reg.code_ = code_ * 2; |
| 241 | 274 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 255 } | 288 } |
| 256 int bit() const { | 289 int bit() const { |
| 257 ASSERT(is_valid()); | 290 ASSERT(is_valid()); |
| 258 return 1 << code_; | 291 return 1 << code_; |
| 259 } | 292 } |
| 260 void split_code(int* vm, int* m) const { | 293 void split_code(int* vm, int* m) const { |
| 261 ASSERT(is_valid()); | 294 ASSERT(is_valid()); |
| 262 *m = (code_ & 0x10) >> 4; | 295 *m = (code_ & 0x10) >> 4; |
| 263 *vm = code_ & 0x0F; | 296 *vm = code_ & 0x0F; |
| 264 } | 297 } |
| 265 | |
| 266 int code_; | |
| 267 }; | 298 }; |
| 268 | 299 |
| 269 | 300 |
| 270 typedef DwVfpRegister DoubleRegister; | 301 // Double word VFP register. |
| 302 struct SoftFloatRegister : ArmDoubleRegister { | |
| 303 static const int kNumRegisters = 1; | |
| 304 static const int kMaxNumAllocatableRegisters = kNumRegisters; | |
| 305 | |
| 306 explicit SoftFloatRegister(int code) : ArmDoubleRegister(code) {} | |
| 307 | |
| 308 static SoftFloatRegister FromAllocationIndex(int index) { | |
| 309 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | |
| 310 return from_code(index); | |
| 311 } | |
| 312 | |
| 313 static const char* AllocationIndexToString(int index) { | |
| 314 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | |
| 315 const char* const names[] = { | |
| 316 "sfpd0" | |
| 317 }; | |
| 318 return names[index]; | |
| 319 } | |
| 320 | |
| 321 static SoftFloatRegister from_code(int code) { | |
| 322 SoftFloatRegister r = SoftFloatRegister(code); | |
| 323 return r; | |
| 324 } | |
| 325 }; | |
| 326 | |
| 327 | |
| 328 typedef ArmDoubleRegister DoubleRegister; | |
| 271 | 329 |
| 272 | 330 |
| 273 // Support for the VFP registers s0 to s31 (d0 to d15). | 331 // 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)". | 332 // Note that "s(N):s(N+1)" is the same as "d(N/2)". |
| 275 const SwVfpRegister s0 = { 0 }; | 333 const SwVfpRegister s0 = { 0 }; |
| 276 const SwVfpRegister s1 = { 1 }; | 334 const SwVfpRegister s1 = { 1 }; |
| 277 const SwVfpRegister s2 = { 2 }; | 335 const SwVfpRegister s2 = { 2 }; |
| 278 const SwVfpRegister s3 = { 3 }; | 336 const SwVfpRegister s3 = { 3 }; |
| 279 const SwVfpRegister s4 = { 4 }; | 337 const SwVfpRegister s4 = { 4 }; |
| 280 const SwVfpRegister s5 = { 5 }; | 338 const SwVfpRegister s5 = { 5 }; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 298 const SwVfpRegister s23 = { 23 }; | 356 const SwVfpRegister s23 = { 23 }; |
| 299 const SwVfpRegister s24 = { 24 }; | 357 const SwVfpRegister s24 = { 24 }; |
| 300 const SwVfpRegister s25 = { 25 }; | 358 const SwVfpRegister s25 = { 25 }; |
| 301 const SwVfpRegister s26 = { 26 }; | 359 const SwVfpRegister s26 = { 26 }; |
| 302 const SwVfpRegister s27 = { 27 }; | 360 const SwVfpRegister s27 = { 27 }; |
| 303 const SwVfpRegister s28 = { 28 }; | 361 const SwVfpRegister s28 = { 28 }; |
| 304 const SwVfpRegister s29 = { 29 }; | 362 const SwVfpRegister s29 = { 29 }; |
| 305 const SwVfpRegister s30 = { 30 }; | 363 const SwVfpRegister s30 = { 30 }; |
| 306 const SwVfpRegister s31 = { 31 }; | 364 const SwVfpRegister s31 = { 31 }; |
| 307 | 365 |
| 308 const DwVfpRegister no_dreg = { -1 }; | 366 const DwVfpRegister no_dreg = DwVfpRegister(-1); |
| 309 const DwVfpRegister d0 = { 0 }; | 367 const DwVfpRegister d0 = DwVfpRegister(0); |
| 310 const DwVfpRegister d1 = { 1 }; | 368 const DwVfpRegister d1 = DwVfpRegister(1); |
| 311 const DwVfpRegister d2 = { 2 }; | 369 const DwVfpRegister d2 = DwVfpRegister(2); |
| 312 const DwVfpRegister d3 = { 3 }; | 370 const DwVfpRegister d3 = DwVfpRegister(3); |
| 313 const DwVfpRegister d4 = { 4 }; | 371 const DwVfpRegister d4 = DwVfpRegister(4); |
| 314 const DwVfpRegister d5 = { 5 }; | 372 const DwVfpRegister d5 = DwVfpRegister(5); |
| 315 const DwVfpRegister d6 = { 6 }; | 373 const DwVfpRegister d6 = DwVfpRegister(6); |
| 316 const DwVfpRegister d7 = { 7 }; | 374 const DwVfpRegister d7 = DwVfpRegister(7); |
| 317 const DwVfpRegister d8 = { 8 }; | 375 const DwVfpRegister d8 = DwVfpRegister(8); |
| 318 const DwVfpRegister d9 = { 9 }; | 376 const DwVfpRegister d9 = DwVfpRegister(9); |
| 319 const DwVfpRegister d10 = { 10 }; | 377 const DwVfpRegister d10 = DwVfpRegister(10); |
| 320 const DwVfpRegister d11 = { 11 }; | 378 const DwVfpRegister d11 = DwVfpRegister(11); |
| 321 const DwVfpRegister d12 = { 12 }; | 379 const DwVfpRegister d12 = DwVfpRegister(12); |
| 322 const DwVfpRegister d13 = { 13 }; | 380 const DwVfpRegister d13 = DwVfpRegister(13); |
| 323 const DwVfpRegister d14 = { 14 }; | 381 const DwVfpRegister d14 = DwVfpRegister(14); |
| 324 const DwVfpRegister d15 = { 15 }; | 382 const DwVfpRegister d15 = DwVfpRegister(15); |
| 383 | |
| 384 const Register sfpd_lo = { kRegister_r6_Code }; | |
| 385 const Register sfpd_hi = { kRegister_r7_Code }; | |
| 325 | 386 |
| 326 // Aliases for double registers. Defined using #define instead of | 387 // Aliases for double registers. Defined using #define instead of |
| 327 // "static const DwVfpRegister&" because Clang complains otherwise when a | 388 // "static const DwVfpRegister&" because Clang complains otherwise when a |
| 328 // compilation unit that includes this header doesn't use the variables. | 389 // compilation unit that includes this header doesn't use the variables. |
| 329 #define kFirstCalleeSavedDoubleReg d8 | 390 #define kFirstCalleeSavedDoubleReg d8 |
| 330 #define kLastCalleeSavedDoubleReg d15 | 391 #define kLastCalleeSavedDoubleReg d15 |
| 331 #define kDoubleRegZero d14 | 392 #define kDoubleRegZero d14 |
| 332 #define kScratchDoubleReg d15 | 393 #define kScratchDoubleReg d15 |
| 333 | 394 |
| 334 | 395 |
| (...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 public: | 1549 public: |
| 1489 explicit EnsureSpace(Assembler* assembler) { | 1550 explicit EnsureSpace(Assembler* assembler) { |
| 1490 assembler->CheckBuffer(); | 1551 assembler->CheckBuffer(); |
| 1491 } | 1552 } |
| 1492 }; | 1553 }; |
| 1493 | 1554 |
| 1494 | 1555 |
| 1495 } } // namespace v8::internal | 1556 } } // namespace v8::internal |
| 1496 | 1557 |
| 1497 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1558 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |