OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 ASSERT(size <= kSizeInBytes); | 179 ASSERT(size <= kSizeInBytes); |
180 T result; | 180 T result; |
181 memset(&result, 0, sizeof(result)); | 181 memset(&result, 0, sizeof(result)); |
182 memcpy(&result, value_, size); | 182 memcpy(&result, value_, size); |
183 return result; | 183 return result; |
184 } | 184 } |
185 | 185 |
186 protected: | 186 protected: |
187 uint8_t value_[kSizeInBytes]; | 187 uint8_t value_[kSizeInBytes]; |
188 }; | 188 }; |
189 typedef SimRegisterBase<kXRegSizeInBytes> SimRegister; // r0-r31 | 189 typedef SimRegisterBase<kXRegSize> SimRegister; // r0-r31 |
190 typedef SimRegisterBase<kDRegSizeInBytes> SimFPRegister; // v0-v31 | 190 typedef SimRegisterBase<kDRegSize> SimFPRegister; // v0-v31 |
191 | 191 |
192 | 192 |
193 class Simulator : public DecoderVisitor { | 193 class Simulator : public DecoderVisitor { |
194 public: | 194 public: |
195 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, | 195 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, |
196 Isolate* isolate = NULL, | 196 Isolate* isolate = NULL, |
197 FILE* stream = stderr); | 197 FILE* stream = stderr); |
198 Simulator(); | 198 Simulator(); |
199 ~Simulator(); | 199 ~Simulator(); |
200 | 200 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 // Declare all Visitor functions. | 351 // Declare all Visitor functions. |
352 #define DECLARE(A) void Visit##A(Instruction* instr); | 352 #define DECLARE(A) void Visit##A(Instruction* instr); |
353 VISITOR_LIST(DECLARE) | 353 VISITOR_LIST(DECLARE) |
354 #undef DECLARE | 354 #undef DECLARE |
355 | 355 |
356 // Register accessors. | 356 // Register accessors. |
357 | 357 |
358 // Return 'size' bits of the value of an integer register, as the specified | 358 // Return 'size' bits of the value of an integer register, as the specified |
359 // type. The value is zero-extended to fill the result. | 359 // type. The value is zero-extended to fill the result. |
360 // | 360 // |
361 // The only supported values of 'size' are kXRegSize and kWRegSize. | 361 // The only supported values of 'size' are kXRegSizeInBits and |
| 362 // kWRegSizeInBits. |
362 template<typename T> | 363 template<typename T> |
363 T reg(unsigned size, unsigned code, | 364 T reg(unsigned size, unsigned code, |
364 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 365 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
365 unsigned size_in_bytes = size / 8; | 366 unsigned size_in_bytes = size / 8; |
366 ASSERT(size_in_bytes <= sizeof(T)); | 367 ASSERT(size_in_bytes <= sizeof(T)); |
367 ASSERT((size == kXRegSize) || (size == kWRegSize)); | 368 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
368 ASSERT(code < kNumberOfRegisters); | 369 ASSERT(code < kNumberOfRegisters); |
369 | 370 |
370 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { | 371 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { |
371 T result; | 372 T result; |
372 memset(&result, 0, sizeof(result)); | 373 memset(&result, 0, sizeof(result)); |
373 return result; | 374 return result; |
374 } | 375 } |
375 return registers_[code].Get<T>(size_in_bytes); | 376 return registers_[code].Get<T>(size_in_bytes); |
376 } | 377 } |
377 | 378 |
(...skipping 15 matching lines...) Expand all Loading... |
393 } | 394 } |
394 | 395 |
395 int64_t reg(unsigned size, unsigned code, | 396 int64_t reg(unsigned size, unsigned code, |
396 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 397 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
397 return reg<int64_t>(size, code, r31mode); | 398 return reg<int64_t>(size, code, r31mode); |
398 } | 399 } |
399 | 400 |
400 // Write 'size' bits of 'value' into an integer register. The value is | 401 // Write 'size' bits of 'value' into an integer register. The value is |
401 // zero-extended. This behaviour matches AArch64 register writes. | 402 // zero-extended. This behaviour matches AArch64 register writes. |
402 // | 403 // |
403 // The only supported values of 'size' are kXRegSize and kWRegSize. | 404 // The only supported values of 'size' are kXRegSizeInBits and |
| 405 // kWRegSizeInBits. |
404 template<typename T> | 406 template<typename T> |
405 void set_reg(unsigned size, unsigned code, T value, | 407 void set_reg(unsigned size, unsigned code, T value, |
406 Reg31Mode r31mode = Reg31IsZeroRegister) { | 408 Reg31Mode r31mode = Reg31IsZeroRegister) { |
407 unsigned size_in_bytes = size / 8; | 409 unsigned size_in_bytes = size / 8; |
408 ASSERT(size_in_bytes <= sizeof(T)); | 410 ASSERT(size_in_bytes <= sizeof(T)); |
409 ASSERT((size == kXRegSize) || (size == kWRegSize)); | 411 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
410 ASSERT(code < kNumberOfRegisters); | 412 ASSERT(code < kNumberOfRegisters); |
411 | 413 |
412 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { | 414 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { |
413 return; | 415 return; |
414 } | 416 } |
415 return registers_[code].Set(value, size_in_bytes); | 417 return registers_[code].Set(value, size_in_bytes); |
416 } | 418 } |
417 | 419 |
418 // Like set_reg(), but infer the access size from the template type. | 420 // Like set_reg(), but infer the access size from the template type. |
419 template<typename T> | 421 template<typename T> |
420 void set_reg(unsigned code, T value, | 422 void set_reg(unsigned code, T value, |
421 Reg31Mode r31mode = Reg31IsZeroRegister) { | 423 Reg31Mode r31mode = Reg31IsZeroRegister) { |
422 set_reg(sizeof(value) * 8, code, value, r31mode); | 424 set_reg(sizeof(value) * 8, code, value, r31mode); |
423 } | 425 } |
424 | 426 |
425 // Common specialized accessors for the set_reg() template. | 427 // Common specialized accessors for the set_reg() template. |
426 void set_wreg(unsigned code, int32_t value, | 428 void set_wreg(unsigned code, int32_t value, |
427 Reg31Mode r31mode = Reg31IsZeroRegister) { | 429 Reg31Mode r31mode = Reg31IsZeroRegister) { |
428 set_reg(kWRegSize, code, value, r31mode); | 430 set_reg(kWRegSizeInBits, code, value, r31mode); |
429 } | 431 } |
430 | 432 |
431 void set_xreg(unsigned code, int64_t value, | 433 void set_xreg(unsigned code, int64_t value, |
432 Reg31Mode r31mode = Reg31IsZeroRegister) { | 434 Reg31Mode r31mode = Reg31IsZeroRegister) { |
433 set_reg(kXRegSize, code, value, r31mode); | 435 set_reg(kXRegSizeInBits, code, value, r31mode); |
434 } | 436 } |
435 | 437 |
436 // Commonly-used special cases. | 438 // Commonly-used special cases. |
437 template<typename T> | 439 template<typename T> |
438 void set_lr(T value) { | 440 void set_lr(T value) { |
439 ASSERT(sizeof(T) == kPointerSize); | 441 ASSERT(sizeof(T) == kPointerSize); |
440 set_reg(kLinkRegCode, value); | 442 set_reg(kLinkRegCode, value); |
441 } | 443 } |
442 | 444 |
443 template<typename T> | 445 template<typename T> |
444 void set_sp(T value) { | 446 void set_sp(T value) { |
445 ASSERT(sizeof(T) == kPointerSize); | 447 ASSERT(sizeof(T) == kPointerSize); |
446 set_reg(31, value, Reg31IsStackPointer); | 448 set_reg(31, value, Reg31IsStackPointer); |
447 } | 449 } |
448 | 450 |
449 int64_t sp() { return xreg(31, Reg31IsStackPointer); } | 451 int64_t sp() { return xreg(31, Reg31IsStackPointer); } |
450 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } | 452 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } |
451 int64_t fp() { | 453 int64_t fp() { |
452 return xreg(kFramePointerRegCode, Reg31IsStackPointer); | 454 return xreg(kFramePointerRegCode, Reg31IsStackPointer); |
453 } | 455 } |
454 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } | 456 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } |
455 | 457 |
456 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } | 458 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } |
457 | 459 |
458 // Return 'size' bits of the value of a floating-point register, as the | 460 // Return 'size' bits of the value of a floating-point register, as the |
459 // specified type. The value is zero-extended to fill the result. | 461 // specified type. The value is zero-extended to fill the result. |
460 // | 462 // |
461 // The only supported values of 'size' are kDRegSize and kSRegSize. | 463 // The only supported values of 'size' are kDRegSizeInBits and |
| 464 // kSRegSizeInBits. |
462 template<typename T> | 465 template<typename T> |
463 T fpreg(unsigned size, unsigned code) const { | 466 T fpreg(unsigned size, unsigned code) const { |
464 unsigned size_in_bytes = size / 8; | 467 unsigned size_in_bytes = size / 8; |
465 ASSERT(size_in_bytes <= sizeof(T)); | 468 ASSERT(size_in_bytes <= sizeof(T)); |
466 ASSERT((size == kDRegSize) || (size == kSRegSize)); | 469 ASSERT((size == kDRegSizeInBits) || (size == kSRegSizeInBits)); |
467 ASSERT(code < kNumberOfFPRegisters); | 470 ASSERT(code < kNumberOfFPRegisters); |
468 return fpregisters_[code].Get<T>(size_in_bytes); | 471 return fpregisters_[code].Get<T>(size_in_bytes); |
469 } | 472 } |
470 | 473 |
471 // Like fpreg(), but infer the access size from the template type. | 474 // Like fpreg(), but infer the access size from the template type. |
472 template<typename T> | 475 template<typename T> |
473 T fpreg(unsigned code) const { | 476 T fpreg(unsigned code) const { |
474 return fpreg<T>(sizeof(T) * 8, code); | 477 return fpreg<T>(sizeof(T) * 8, code); |
475 } | 478 } |
476 | 479 |
477 // Common specialized accessors for the fpreg() template. | 480 // Common specialized accessors for the fpreg() template. |
478 float sreg(unsigned code) const { | 481 float sreg(unsigned code) const { |
479 return fpreg<float>(code); | 482 return fpreg<float>(code); |
480 } | 483 } |
481 | 484 |
482 uint32_t sreg_bits(unsigned code) const { | 485 uint32_t sreg_bits(unsigned code) const { |
483 return fpreg<uint32_t>(code); | 486 return fpreg<uint32_t>(code); |
484 } | 487 } |
485 | 488 |
486 double dreg(unsigned code) const { | 489 double dreg(unsigned code) const { |
487 return fpreg<double>(code); | 490 return fpreg<double>(code); |
488 } | 491 } |
489 | 492 |
490 uint64_t dreg_bits(unsigned code) const { | 493 uint64_t dreg_bits(unsigned code) const { |
491 return fpreg<uint64_t>(code); | 494 return fpreg<uint64_t>(code); |
492 } | 495 } |
493 | 496 |
494 double fpreg(unsigned size, unsigned code) const { | 497 double fpreg(unsigned size, unsigned code) const { |
495 switch (size) { | 498 switch (size) { |
496 case kSRegSize: return sreg(code); | 499 case kSRegSizeInBits: return sreg(code); |
497 case kDRegSize: return dreg(code); | 500 case kDRegSizeInBits: return dreg(code); |
498 default: | 501 default: |
499 UNREACHABLE(); | 502 UNREACHABLE(); |
500 return 0.0; | 503 return 0.0; |
501 } | 504 } |
502 } | 505 } |
503 | 506 |
504 // Write 'value' into a floating-point register. The value is zero-extended. | 507 // Write 'value' into a floating-point register. The value is zero-extended. |
505 // This behaviour matches AArch64 register writes. | 508 // This behaviour matches AArch64 register writes. |
506 template<typename T> | 509 template<typename T> |
507 void set_fpreg(unsigned code, T value) { | 510 void set_fpreg(unsigned code, T value) { |
508 ASSERT((sizeof(value) == kDRegSizeInBytes) || | 511 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); |
509 (sizeof(value) == kSRegSizeInBytes)); | |
510 ASSERT(code < kNumberOfFPRegisters); | 512 ASSERT(code < kNumberOfFPRegisters); |
511 fpregisters_[code].Set(value, sizeof(value)); | 513 fpregisters_[code].Set(value, sizeof(value)); |
512 } | 514 } |
513 | 515 |
514 // Common specialized accessors for the set_fpreg() template. | 516 // Common specialized accessors for the set_fpreg() template. |
515 void set_sreg(unsigned code, float value) { | 517 void set_sreg(unsigned code, float value) { |
516 set_fpreg(code, value); | 518 set_fpreg(code, value); |
517 } | 519 } |
518 | 520 |
519 void set_sreg_bits(unsigned code, uint32_t value) { | 521 void set_sreg_bits(unsigned code, uint32_t value) { |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 static void UnregisterCTryCatch() { | 874 static void UnregisterCTryCatch() { |
873 Simulator::current(Isolate::Current())->PopAddress(); | 875 Simulator::current(Isolate::Current())->PopAddress(); |
874 } | 876 } |
875 }; | 877 }; |
876 | 878 |
877 #endif // !defined(USE_SIMULATOR) | 879 #endif // !defined(USE_SIMULATOR) |
878 | 880 |
879 } } // namespace v8::internal | 881 } } // namespace v8::internal |
880 | 882 |
881 #endif // V8_A64_SIMULATOR_A64_H_ | 883 #endif // V8_A64_SIMULATOR_A64_H_ |
OLD | NEW |