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

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

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

Powered by Google App Engine
This is Rietveld 408576698