Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: src/arm64/simulator-arm64.h

Issue 213943002: Change arm64 simulator register backing store. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm64/simulator-arm64.cc » ('j') | src/arm64/simulator-arm64.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_ 5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_
6 #define V8_ARM64_SIMULATOR_ARM64_H_ 6 #define V8_ARM64_SIMULATOR_ARM64_H_
7 7
8 #include <stdarg.h> 8 #include <stdarg.h>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // describes the bits which are not modifiable. 126 // describes the bits which are not modifiable.
127 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) 127 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
128 : value_(value), write_ignore_mask_(write_ignore_mask) { } 128 : value_(value), write_ignore_mask_(write_ignore_mask) { }
129 129
130 uint32_t value_; 130 uint32_t value_;
131 uint32_t write_ignore_mask_; 131 uint32_t write_ignore_mask_;
132 }; 132 };
133 133
134 134
135 // Represent a register (r0-r31, v0-v31). 135 // Represent a register (r0-r31, v0-v31).
136 template<int kSizeInBytes>
137 class SimRegisterBase { 136 class SimRegisterBase {
138 public: 137 public:
139 template<typename T> 138 template<typename T>
140 void Set(T new_value, unsigned size = sizeof(T)) { 139 void Set(T new_value) {
141 ASSERT(size <= kSizeInBytes); 140 value_ = 0;
142 ASSERT(size <= sizeof(new_value)); 141 memcpy(&value_, &new_value, sizeof(T));
143 // All AArch64 registers are zero-extending; Writing a W register clears the
144 // top bits of the corresponding X register.
145 memset(value_, 0, kSizeInBytes);
146 memcpy(value_, &new_value, size);
147 } 142 }
148 143
149 // Copy 'size' bytes of the register to the result, and zero-extend to fill
150 // the result.
151 template<typename T> 144 template<typename T>
152 T Get(unsigned size = sizeof(T)) const { 145 T Get() const {
153 ASSERT(size <= kSizeInBytes);
154 T result; 146 T result;
155 memset(&result, 0, sizeof(result)); 147 memcpy(&result, &value_, sizeof(T));
156 memcpy(&result, value_, size);
157 return result; 148 return result;
158 } 149 }
159 150
160 protected: 151 protected:
161 uint8_t value_[kSizeInBytes]; 152 int64_t value_;
162 }; 153 };
163 typedef SimRegisterBase<kXRegSize> SimRegister; // r0-r31 154
164 typedef SimRegisterBase<kDRegSize> SimFPRegister; // v0-v31 155
156 typedef SimRegisterBase SimRegister; // r0-r31
157 typedef SimRegisterBase SimFPRegister; // v0-v31
165 158
166 159
167 class Simulator : public DecoderVisitor { 160 class Simulator : public DecoderVisitor {
168 public: 161 public:
169 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, 162 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
170 Isolate* isolate = NULL, 163 Isolate* isolate = NULL,
171 FILE* stream = stderr); 164 FILE* stream = stderr);
172 Simulator(); 165 Simulator();
173 ~Simulator(); 166 ~Simulator();
174 167
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 LogProcessorState(); 314 LogProcessorState();
322 increment_pc(); 315 increment_pc();
323 CheckBreakpoints(); 316 CheckBreakpoints();
324 } 317 }
325 318
326 // Declare all Visitor functions. 319 // Declare all Visitor functions.
327 #define DECLARE(A) void Visit##A(Instruction* instr); 320 #define DECLARE(A) void Visit##A(Instruction* instr);
328 VISITOR_LIST(DECLARE) 321 VISITOR_LIST(DECLARE)
329 #undef DECLARE 322 #undef DECLARE
330 323
324 bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const {
325 return ((code == 31) && (r31mode == Reg31IsZeroRegister));
326 }
327
331 // Register accessors. 328 // Register accessors.
332
333 // Return 'size' bits of the value of an integer register, as the specified 329 // Return 'size' bits of the value of an integer register, as the specified
334 // type. The value is zero-extended to fill the result. 330 // type. The value is zero-extended to fill the result.
335 // 331 //
336 // The only supported values of 'size' are kXRegSizeInBits and
337 // kWRegSizeInBits.
338 template<typename T>
339 T reg(unsigned size, unsigned code,
340 Reg31Mode r31mode = Reg31IsZeroRegister) const {
341 unsigned size_in_bytes = size / 8;
342 ASSERT(size_in_bytes <= sizeof(T));
343 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits));
344 ASSERT(code < kNumberOfRegisters);
345
346 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
347 T result;
348 memset(&result, 0, sizeof(result));
349 return result;
350 }
351 return registers_[code].Get<T>(size_in_bytes);
352 }
353
354 // Like reg(), but infer the access size from the template type.
355 template<typename T> 332 template<typename T>
356 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 333 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
357 return reg<T>(sizeof(T) * 8, code, r31mode); 334 ASSERT(code < kNumberOfRegisters);
335 if (IsZeroRegister(code, r31mode)) {
336 return 0;
337 }
338 return registers_[code].Get<T>();
358 } 339 }
359 340
360 // Common specialized accessors for the reg() template. 341 // Common specialized accessors for the reg() template.
361 int32_t wreg(unsigned code, 342 int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
362 Reg31Mode r31mode = Reg31IsZeroRegister) const {
363 return reg<int32_t>(code, r31mode); 343 return reg<int32_t>(code, r31mode);
364 } 344 }
365 345
366 int64_t xreg(unsigned code, 346 int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
367 Reg31Mode r31mode = Reg31IsZeroRegister) const {
368 return reg<int64_t>(code, r31mode); 347 return reg<int64_t>(code, r31mode);
369 } 348 }
370 349
371 int64_t reg(unsigned size, unsigned code,
372 Reg31Mode r31mode = Reg31IsZeroRegister) const {
373 return reg<int64_t>(size, code, r31mode);
374 }
375
376 // Write 'size' bits of 'value' into an integer register. The value is 350 // Write 'size' bits of 'value' into an integer register. The value is
377 // zero-extended. This behaviour matches AArch64 register writes. 351 // zero-extended. This behaviour matches AArch64 register writes.
378 //
379 // The only supported values of 'size' are kXRegSizeInBits and
380 // kWRegSizeInBits.
381 template<typename T>
382 void set_reg(unsigned size, unsigned code, T value,
383 Reg31Mode r31mode = Reg31IsZeroRegister) {
384 unsigned size_in_bytes = size / 8;
385 ASSERT(size_in_bytes <= sizeof(T));
386 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits));
387 ASSERT(code < kNumberOfRegisters);
388
389 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
390 return;
391 }
392 return registers_[code].Set(value, size_in_bytes);
393 }
394 352
395 // Like set_reg(), but infer the access size from the template type. 353 // Like set_reg(), but infer the access size from the template type.
396 template<typename T> 354 template<typename T>
397 void set_reg(unsigned code, T value, 355 void set_reg(unsigned code, T value,
398 Reg31Mode r31mode = Reg31IsZeroRegister) { 356 Reg31Mode r31mode = Reg31IsZeroRegister) {
399 set_reg(sizeof(value) * 8, code, value, r31mode); 357 ASSERT(code < kNumberOfRegisters);
358 if (!IsZeroRegister(code, r31mode))
359 registers_[code].Set(value);
400 } 360 }
401 361
402 // Common specialized accessors for the set_reg() template. 362 // Common specialized accessors for the set_reg() template.
403 void set_wreg(unsigned code, int32_t value, 363 void set_wreg(unsigned code, int32_t value,
404 Reg31Mode r31mode = Reg31IsZeroRegister) { 364 Reg31Mode r31mode = Reg31IsZeroRegister) {
405 set_reg(kWRegSizeInBits, code, value, r31mode); 365 set_reg(code, value, r31mode);
406 } 366 }
407 367
408 void set_xreg(unsigned code, int64_t value, 368 void set_xreg(unsigned code, int64_t value,
409 Reg31Mode r31mode = Reg31IsZeroRegister) { 369 Reg31Mode r31mode = Reg31IsZeroRegister) {
410 set_reg(kXRegSizeInBits, code, value, r31mode); 370 set_reg(code, value, r31mode);
411 } 371 }
412 372
413 // Commonly-used special cases. 373 // Commonly-used special cases.
414 template<typename T> 374 template<typename T>
415 void set_lr(T value) { 375 void set_lr(T value) {
416 ASSERT(sizeof(T) == kPointerSize); 376 ASSERT(sizeof(T) == kPointerSize);
417 set_reg(kLinkRegCode, value); 377 set_reg(kLinkRegCode, value);
418 } 378 }
419 379
420 template<typename T> 380 template<typename T>
421 void set_sp(T value) { 381 void set_sp(T value) {
422 ASSERT(sizeof(T) == kPointerSize); 382 ASSERT(sizeof(T) == kPointerSize);
423 set_reg(31, value, Reg31IsStackPointer); 383 set_reg(31, value, Reg31IsStackPointer);
424 } 384 }
425 385
426 int64_t sp() { return xreg(31, Reg31IsStackPointer); } 386 int64_t sp() { return xreg(31, Reg31IsStackPointer); }
427 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } 387 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); }
428 int64_t fp() { 388 int64_t fp() {
429 return xreg(kFramePointerRegCode, Reg31IsStackPointer); 389 return xreg(kFramePointerRegCode, Reg31IsStackPointer);
430 } 390 }
431 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } 391 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
432 392
433 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } 393 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); }
434 394
435 // Return 'size' bits of the value of a floating-point register, as the
436 // specified type. The value is zero-extended to fill the result.
437 //
438 // The only supported values of 'size' are kDRegSizeInBits and
439 // kSRegSizeInBits.
440 template<typename T>
441 T fpreg(unsigned size, unsigned code) const {
442 unsigned size_in_bytes = size / 8;
443 ASSERT(size_in_bytes <= sizeof(T));
444 ASSERT((size == kDRegSizeInBits) || (size == kSRegSizeInBits));
445 ASSERT(code < kNumberOfFPRegisters);
446 return fpregisters_[code].Get<T>(size_in_bytes);
447 }
448
449 // Like fpreg(), but infer the access size from the template type.
450 template<typename T> 395 template<typename T>
451 T fpreg(unsigned code) const { 396 T fpreg(unsigned code) const {
452 return fpreg<T>(sizeof(T) * 8, code); 397 ASSERT(code < kNumberOfRegisters);
398 return fpregisters_[code].Get<T>();
453 } 399 }
454 400
455 // Common specialized accessors for the fpreg() template. 401 // Common specialized accessors for the fpreg() template.
456 float sreg(unsigned code) const { 402 float sreg(unsigned code) const {
457 return fpreg<float>(code); 403 return fpreg<float>(code);
458 } 404 }
459 405
460 uint32_t sreg_bits(unsigned code) const { 406 uint32_t sreg_bits(unsigned code) const {
461 return fpreg<uint32_t>(code); 407 return fpreg<uint32_t>(code);
462 } 408 }
(...skipping 15 matching lines...) Expand all
478 return 0.0; 424 return 0.0;
479 } 425 }
480 } 426 }
481 427
482 // Write 'value' into a floating-point register. The value is zero-extended. 428 // Write 'value' into a floating-point register. The value is zero-extended.
483 // This behaviour matches AArch64 register writes. 429 // This behaviour matches AArch64 register writes.
484 template<typename T> 430 template<typename T>
485 void set_fpreg(unsigned code, T value) { 431 void set_fpreg(unsigned code, T value) {
486 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); 432 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize));
487 ASSERT(code < kNumberOfFPRegisters); 433 ASSERT(code < kNumberOfFPRegisters);
488 fpregisters_[code].Set(value, sizeof(value)); 434 fpregisters_[code].Set(value);
489 } 435 }
490 436
491 // Common specialized accessors for the set_fpreg() template. 437 // Common specialized accessors for the set_fpreg() template.
492 void set_sreg(unsigned code, float value) { 438 void set_sreg(unsigned code, float value) {
493 set_fpreg(code, value); 439 set_fpreg(code, value);
494 } 440 }
495 441
496 void set_sreg_bits(unsigned code, uint32_t value) { 442 void set_sreg_bits(unsigned code, uint32_t value) {
497 set_fpreg(code, value); 443 set_fpreg(code, value);
498 } 444 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 default: 564 default:
619 UNREACHABLE(); 565 UNREACHABLE();
620 return false; 566 return false;
621 } 567 }
622 } 568 }
623 569
624 bool ConditionFailed(Condition cond) { 570 bool ConditionFailed(Condition cond) {
625 return !ConditionPassed(cond); 571 return !ConditionPassed(cond);
626 } 572 }
627 573
628 void AddSubHelper(Instruction* instr, int64_t op2); 574 template<typename T>
629 int64_t AddWithCarry(unsigned reg_size, 575 void AddSubHelper(Instruction* instr, T op2);
630 bool set_flags, 576 template<typename T>
631 int64_t src1, 577 T AddWithCarry(bool set_flags,
632 int64_t src2, 578 T src1,
633 int64_t carry_in = 0); 579 T src2,
634 void LogicalHelper(Instruction* instr, int64_t op2); 580 T carry_in = 0);
635 void ConditionalCompareHelper(Instruction* instr, int64_t op2); 581 template<typename T>
582 void AddSubWithCarry(Instruction* instr);
583 template<typename T>
584 void LogicalHelper(Instruction* instr, T op2);
585 template<typename T>
586 void ConditionalCompareHelper(Instruction* instr, T op2);
636 void LoadStoreHelper(Instruction* instr, 587 void LoadStoreHelper(Instruction* instr,
637 int64_t offset, 588 int64_t offset,
638 AddrMode addrmode); 589 AddrMode addrmode);
639 void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); 590 void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
640 uint8_t* LoadStoreAddress(unsigned addr_reg, 591 uint8_t* LoadStoreAddress(unsigned addr_reg,
641 int64_t offset, 592 int64_t offset,
642 AddrMode addrmode); 593 AddrMode addrmode);
643 void LoadStoreWriteBack(unsigned addr_reg, 594 void LoadStoreWriteBack(unsigned addr_reg,
644 int64_t offset, 595 int64_t offset,
645 AddrMode addrmode); 596 AddrMode addrmode);
646 void CheckMemoryAccess(uint8_t* address, uint8_t* stack); 597 void CheckMemoryAccess(uint8_t* address, uint8_t* stack);
647 598
648 uint64_t MemoryRead(uint8_t* address, unsigned num_bytes); 599 uint64_t MemoryRead(uint8_t* address, unsigned num_bytes);
649 uint8_t MemoryRead8(uint8_t* address); 600 uint8_t MemoryRead8(uint8_t* address);
650 uint16_t MemoryRead16(uint8_t* address); 601 uint16_t MemoryRead16(uint8_t* address);
651 uint32_t MemoryRead32(uint8_t* address); 602 uint32_t MemoryRead32(uint8_t* address);
652 float MemoryReadFP32(uint8_t* address); 603 float MemoryReadFP32(uint8_t* address);
653 uint64_t MemoryRead64(uint8_t* address); 604 uint64_t MemoryRead64(uint8_t* address);
654 double MemoryReadFP64(uint8_t* address); 605 double MemoryReadFP64(uint8_t* address);
655 606
656 void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes); 607 void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes);
657 void MemoryWrite32(uint8_t* address, uint32_t value); 608 void MemoryWrite32(uint8_t* address, uint32_t value);
658 void MemoryWriteFP32(uint8_t* address, float value); 609 void MemoryWriteFP32(uint8_t* address, float value);
659 void MemoryWrite64(uint8_t* address, uint64_t value); 610 void MemoryWrite64(uint8_t* address, uint64_t value);
660 void MemoryWriteFP64(uint8_t* address, double value); 611 void MemoryWriteFP64(uint8_t* address, double value);
661 612
662 int64_t ShiftOperand(unsigned reg_size, 613
663 int64_t value, 614 template <typename T>
664 Shift shift_type, 615 T ShiftOperand(T value,
665 unsigned amount);
666 int64_t Rotate(unsigned reg_width,
667 int64_t value,
668 Shift shift_type, 616 Shift shift_type,
669 unsigned amount); 617 unsigned amount);
670 int64_t ExtendValue(unsigned reg_width, 618 template <typename T>
671 int64_t value, 619 T ExtendValue(T value,
672 Extend extend_type, 620 Extend extend_type,
673 unsigned left_shift = 0); 621 unsigned left_shift = 0);
622 template <typename T>
623 void Extract(Instruction* instr);
624 template <typename T>
625 void DataProcessing2Source(Instruction* instr);
626 template <typename T>
627 void BitfieldHelper(Instruction* instr);
674 628
675 uint64_t ReverseBits(uint64_t value, unsigned num_bits); 629 uint64_t ReverseBits(uint64_t value, unsigned num_bits);
676 uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode); 630 uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode);
677 631
678 template <typename T> 632 template <typename T>
679 T FPDefaultNaN() const; 633 T FPDefaultNaN() const;
680 634
681 void FPCompare(double val0, double val1); 635 void FPCompare(double val0, double val1);
682 double FPRoundInt(double value, FPRounding round_mode); 636 double FPRoundInt(double value, FPRounding round_mode);
683 double FPToDouble(float value); 637 double FPToDouble(float value);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // functions, or to save and restore it when entering and leaving generated 743 // functions, or to save and restore it when entering and leaving generated
790 // code. 744 // code.
791 void AssertSupportedFPCR() { 745 void AssertSupportedFPCR() {
792 ASSERT(fpcr().FZ() == 0); // No flush-to-zero support. 746 ASSERT(fpcr().FZ() == 0); // No flush-to-zero support.
793 ASSERT(fpcr().RMode() == FPTieEven); // Ties-to-even rounding only. 747 ASSERT(fpcr().RMode() == FPTieEven); // Ties-to-even rounding only.
794 748
795 // The simulator does not support half-precision operations so fpcr().AHP() 749 // The simulator does not support half-precision operations so fpcr().AHP()
796 // is irrelevant, and is not checked here. 750 // is irrelevant, and is not checked here.
797 } 751 }
798 752
799 static int CalcNFlag(uint64_t result, unsigned reg_size) { 753 template <typename T>
800 return (result >> (reg_size - 1)) & 1; 754 static int CalcNFlag(T result) {
755 return (result >> (sizeof(T) * 8 - 1)) & 1;
801 } 756 }
802 757
803 static int CalcZFlag(uint64_t result) { 758 static int CalcZFlag(uint64_t result) {
804 return result == 0; 759 return result == 0;
805 } 760 }
806 761
807 static const uint32_t kConditionFlagsMask = 0xf0000000; 762 static const uint32_t kConditionFlagsMask = 0xf0000000;
808 763
809 // Stack 764 // Stack
810 byte* stack_; 765 byte* stack_;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 static void UnregisterCTryCatch() { 828 static void UnregisterCTryCatch() {
874 Simulator::current(Isolate::Current())->PopAddress(); 829 Simulator::current(Isolate::Current())->PopAddress();
875 } 830 }
876 }; 831 };
877 832
878 #endif // !defined(USE_SIMULATOR) 833 #endif // !defined(USE_SIMULATOR)
879 834
880 } } // namespace v8::internal 835 } } // namespace v8::internal
881 836
882 #endif // V8_ARM64_SIMULATOR_ARM64_H_ 837 #endif // V8_ARM64_SIMULATOR_ARM64_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm64/simulator-arm64.cc » ('j') | src/arm64/simulator-arm64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698