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

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, 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') | 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 68
69 static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 69 static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
70 return try_catch_address; 70 return try_catch_address;
71 } 71 }
72 72
73 static void UnregisterCTryCatch() { } 73 static void UnregisterCTryCatch() { }
74 }; 74 };
75 75
76 #else // !defined(USE_SIMULATOR) 76 #else // !defined(USE_SIMULATOR)
77 77
78
79 template<typename T>
80 struct make_unsigned {
81 typedef T type;
82 };
83
84
78 enum ReverseByteMode { 85 enum ReverseByteMode {
79 Reverse16 = 0, 86 Reverse16 = 0,
80 Reverse32 = 1, 87 Reverse32 = 1,
81 Reverse64 = 2 88 Reverse64 = 2
82 }; 89 };
83 90
84 91
85 // The proper way to initialize a simulated system register (such as NZCV) is as 92 // The proper way to initialize a simulated system register (such as NZCV) is as
86 // follows: 93 // follows:
87 // SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); 94 // SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // describes the bits which are not modifiable. 136 // describes the bits which are not modifiable.
130 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) 137 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
131 : value_(value), write_ignore_mask_(write_ignore_mask) { } 138 : value_(value), write_ignore_mask_(write_ignore_mask) { }
132 139
133 uint32_t value_; 140 uint32_t value_;
134 uint32_t write_ignore_mask_; 141 uint32_t write_ignore_mask_;
135 }; 142 };
136 143
137 144
138 // Represent a register (r0-r31, v0-v31). 145 // Represent a register (r0-r31, v0-v31).
139 template<int kSizeInBytes>
140 class SimRegisterBase { 146 class SimRegisterBase {
141 public: 147 public:
142 template<typename T> 148 void Set(int64_t new_value, unsigned size) {
143 void Set(T new_value, unsigned size = sizeof(T)) { 149 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits));
144 ASSERT(size <= kSizeInBytes);
145 ASSERT(size <= sizeof(new_value));
146 // All AArch64 registers are zero-extending; Writing a W register clears the 150 // All AArch64 registers are zero-extending; Writing a W register clears the
147 // top bits of the corresponding X register. 151 // top bits of the corresponding X register.
148 memset(value_, 0, kSizeInBytes); 152 value_ = new_value;
Sven Panne 2014/05/16 11:15:47 A ternary is a bit more readable here: value_ =
jbramley 2014/05/16 14:05:50 You probably need to set the value just once, to a
149 memcpy(value_, &new_value, size); 153 STATIC_ASSERT(kWRegSizeInBits == kSRegSizeInBits);
154 if (size == kWRegSizeInBits) {
155 value_ &= kWRegMask;
156 }
jbramley 2014/05/16 14:05:50 else { ASSERT(size == (sizeof(value_) * kByteSiz
157 }
158
159 template<typename T>
160 void Set(T new_value) {
Sven Panne 2014/05/16 11:15:47 This method and the corresponding templatized Get
jbramley 2014/05/16 14:05:50 Indeed; I'd like to see what you're aiming for. I
Fritz 2014/05/16 18:11:46 My direction is to only use the templatized Get/Se
161 value_ = 0;
162 memcpy(&value_, &new_value, sizeof(T));
150 } 163 }
151 164
152 // Copy 'size' bytes of the register to the result, and zero-extend to fill 165 // Copy 'size' bytes of the register to the result, and zero-extend to fill
153 // the result. 166 // the result.
167 int64_t Get(unsigned size) const {
168 ASSERT(size/8 <= kXRegSize);
169 int64_t result = value_;
Sven Panne 2014/05/16 11:15:47 I think a ternary is more readable here, too:
170 if (size == kSRegSizeInBits) {
jbramley 2014/05/16 14:05:50 Use of SRegSize is surprising here; use WRegSize i
171 result &= kSRegMask;
172 }
173 return result;
174 }
175
154 template<typename T> 176 template<typename T>
155 T Get(unsigned size = sizeof(T)) const { 177 T Get() const {
156 ASSERT(size <= kSizeInBytes);
157 T result; 178 T result;
158 memset(&result, 0, sizeof(result)); 179 memcpy(&result, &value_, sizeof(T));
159 memcpy(&result, value_, size);
160 return result; 180 return result;
161 } 181 }
162 182
163 protected: 183 protected:
164 uint8_t value_[kSizeInBytes]; 184 int64_t value_;
jbramley 2014/05/16 14:05:50 Have you thought about how NEON Q registers might
Fritz 2014/05/16 18:11:46 I don't have a fully formed solution yet. I do re
165 }; 185 };
166 typedef SimRegisterBase<kXRegSize> SimRegister; // r0-r31 186
167 typedef SimRegisterBase<kDRegSize> SimFPRegister; // v0-v31 187 STATIC_ASSERT(kXRegSize == kDRegSize);
jbramley 2014/05/16 14:05:50 It'd be better to put this next to the declaration
188 typedef SimRegisterBase SimRegister; // r0-r31
189 typedef SimRegisterBase SimFPRegister; // v0-v31
168 190
169 191
170 class Simulator : public DecoderVisitor { 192 class Simulator : public DecoderVisitor {
171 public: 193 public:
172 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, 194 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
173 Isolate* isolate = NULL, 195 Isolate* isolate = NULL,
174 FILE* stream = stderr); 196 FILE* stream = stderr);
175 Simulator(); 197 Simulator();
176 ~Simulator(); 198 ~Simulator();
177 199
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 LogProcessorState(); 346 LogProcessorState();
325 increment_pc(); 347 increment_pc();
326 CheckBreakpoints(); 348 CheckBreakpoints();
327 } 349 }
328 350
329 // Declare all Visitor functions. 351 // Declare all Visitor functions.
330 #define DECLARE(A) void Visit##A(Instruction* instr); 352 #define DECLARE(A) void Visit##A(Instruction* instr);
331 VISITOR_LIST(DECLARE) 353 VISITOR_LIST(DECLARE)
332 #undef DECLARE 354 #undef DECLARE
333 355
356 bool Reg31ZeroMode(unsigned code, Reg31Mode r31mode) const {
jbramley 2014/05/16 14:05:50 `IsZeroRegister(...)` would be a better name.
Fritz 2014/05/16 18:11:46 Done.
357 return ((code == 31) && (r31mode == Reg31IsZeroRegister));
358 }
359
334 // Register accessors. 360 // Register accessors.
335
336 // Return 'size' bits of the value of an integer register, as the specified 361 // Return 'size' bits of the value of an integer register, as the specified
337 // type. The value is zero-extended to fill the result. 362 // type. The value is zero-extended to fill the result.
338 // 363 //
339 // The only supported values of 'size' are kXRegSizeInBits and 364 // The only supported values of 'size' are kXRegSizeInBits and
340 // kWRegSizeInBits. 365 // kWRegSizeInBits.
341 template<typename T> 366 int64_t reg(unsigned size, unsigned code,
342 T reg(unsigned size, unsigned code,
343 Reg31Mode r31mode = Reg31IsZeroRegister) const { 367 Reg31Mode r31mode = Reg31IsZeroRegister) const {
344 unsigned size_in_bytes = size / 8;
345 ASSERT(size_in_bytes <= sizeof(T));
346 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); 368 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits));
347 ASSERT(code < kNumberOfRegisters); 369 ASSERT(code < kNumberOfRegisters);
348 370
349 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 371 if (Reg31ZeroMode(code, r31mode)) {
350 T result; 372 return 0;
351 memset(&result, 0, sizeof(result));
352 return result;
353 } 373 }
354 return registers_[code].Get<T>(size_in_bytes); 374 return registers_[code].Get(size);
355 } 375 }
356 376
357 // Like reg(), but infer the access size from the template type. 377 // Like reg(), but infer the access size from the template type.
358 template<typename T> 378 template<typename T>
359 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 379 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
360 return reg<T>(sizeof(T) * 8, code, r31mode); 380 ASSERT(code < kNumberOfRegisters);
381 if (Reg31ZeroMode(code, r31mode)) {
382 return 0;
383 }
384 return registers_[code].Get<T>();
361 } 385 }
362 386
363 // Common specialized accessors for the reg() template. 387 // Common specialized accessors for the reg() template.
364 int32_t wreg(unsigned code, 388 int32_t wreg(unsigned code,
365 Reg31Mode r31mode = Reg31IsZeroRegister) const { 389 Reg31Mode r31mode = Reg31IsZeroRegister) const {
366 return reg<int32_t>(code, r31mode); 390 return reg<int32_t>(code, r31mode);
367 } 391 }
368 392
369 int64_t xreg(unsigned code, 393 int64_t xreg(unsigned code,
370 Reg31Mode r31mode = Reg31IsZeroRegister) const { 394 Reg31Mode r31mode = Reg31IsZeroRegister) const {
371 return reg<int64_t>(code, r31mode); 395 return reg<int64_t>(code, r31mode);
372 } 396 }
373 397
374 int64_t reg(unsigned size, unsigned code,
375 Reg31Mode r31mode = Reg31IsZeroRegister) const {
376 return reg<int64_t>(size, code, r31mode);
377 }
378
379 // Write 'size' bits of 'value' into an integer register. The value is 398 // Write 'size' bits of 'value' into an integer register. The value is
380 // zero-extended. This behaviour matches AArch64 register writes. 399 // zero-extended. This behaviour matches AArch64 register writes.
381 // 400 //
382 // The only supported values of 'size' are kXRegSizeInBits and 401 // The only supported values of 'size' are kXRegSizeInBits and
383 // kWRegSizeInBits. 402 // kWRegSizeInBits.
384 template<typename T> 403 template<typename T>
385 void set_reg(unsigned size, unsigned code, T value, 404 void set_reg(unsigned size, unsigned code, T value,
386 Reg31Mode r31mode = Reg31IsZeroRegister) { 405 Reg31Mode r31mode = Reg31IsZeroRegister) {
387 unsigned size_in_bytes = size / 8;
388 ASSERT(size_in_bytes <= sizeof(T));
389 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); 406 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits));
390 ASSERT(code < kNumberOfRegisters); 407 ASSERT(code < kNumberOfRegisters);
391 408
392 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 409 if (!Reg31ZeroMode(code, r31mode))
393 return; 410 registers_[code].Set(value, size);
394 }
395 return registers_[code].Set(value, size_in_bytes);
396 } 411 }
397 412
398 // Like set_reg(), but infer the access size from the template type. 413 // Like set_reg(), but infer the access size from the template type.
399 template<typename T> 414 template<typename T>
400 void set_reg(unsigned code, T value, 415 void set_reg(unsigned code, T value,
401 Reg31Mode r31mode = Reg31IsZeroRegister) { 416 Reg31Mode r31mode = Reg31IsZeroRegister) {
402 set_reg(sizeof(value) * 8, code, value, r31mode); 417 ASSERT(code < kNumberOfRegisters);
418 if (!Reg31ZeroMode(code, r31mode))
419 registers_[code].Set(value);
403 } 420 }
404 421
405 // Common specialized accessors for the set_reg() template. 422 // Common specialized accessors for the set_reg() template.
406 void set_wreg(unsigned code, int32_t value, 423 void set_wreg(unsigned code, int32_t value,
407 Reg31Mode r31mode = Reg31IsZeroRegister) { 424 Reg31Mode r31mode = Reg31IsZeroRegister) {
408 set_reg(kWRegSizeInBits, code, value, r31mode); 425 set_reg(code, value, r31mode);
409 } 426 }
410 427
411 void set_xreg(unsigned code, int64_t value, 428 void set_xreg(unsigned code, int64_t value,
412 Reg31Mode r31mode = Reg31IsZeroRegister) { 429 Reg31Mode r31mode = Reg31IsZeroRegister) {
413 set_reg(kXRegSizeInBits, code, value, r31mode); 430 set_reg(code, value, r31mode);
414 } 431 }
415 432
416 // Commonly-used special cases. 433 // Commonly-used special cases.
417 template<typename T> 434 template<typename T>
418 void set_lr(T value) { 435 void set_lr(T value) {
419 ASSERT(sizeof(T) == kPointerSize); 436 ASSERT(sizeof(T) == kPointerSize);
420 set_reg(kLinkRegCode, value); 437 set_reg(kLinkRegCode, value);
421 } 438 }
422 439
423 template<typename T> 440 template<typename T>
424 void set_sp(T value) { 441 void set_sp(T value) {
425 ASSERT(sizeof(T) == kPointerSize); 442 ASSERT(sizeof(T) == kPointerSize);
426 set_reg(31, value, Reg31IsStackPointer); 443 set_reg(31, value, Reg31IsStackPointer);
427 } 444 }
428 445
429 int64_t sp() { return xreg(31, Reg31IsStackPointer); } 446 int64_t sp() { return xreg(31, Reg31IsStackPointer); }
430 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } 447 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); }
431 int64_t fp() { 448 int64_t fp() {
432 return xreg(kFramePointerRegCode, Reg31IsStackPointer); 449 return xreg(kFramePointerRegCode, Reg31IsStackPointer);
433 } 450 }
434 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } 451 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
435 452
436 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } 453 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); }
437 454
438 // Return 'size' bits of the value of a floating-point register, as the
439 // specified type. The value is zero-extended to fill the result.
440 //
441 // The only supported values of 'size' are kDRegSizeInBits and
442 // kSRegSizeInBits.
443 template<typename T>
444 T fpreg(unsigned size, unsigned code) const {
445 unsigned size_in_bytes = size / 8;
446 ASSERT(size_in_bytes <= sizeof(T));
447 ASSERT((size == kDRegSizeInBits) || (size == kSRegSizeInBits));
448 ASSERT(code < kNumberOfFPRegisters);
449 return fpregisters_[code].Get<T>(size_in_bytes);
450 }
451
452 // Like fpreg(), but infer the access size from the template type.
453 template<typename T> 455 template<typename T>
454 T fpreg(unsigned code) const { 456 T fpreg(unsigned code) const {
455 return fpreg<T>(sizeof(T) * 8, code); 457 ASSERT(code < kNumberOfRegisters);
458 return fpregisters_[code].Get<T>();
456 } 459 }
457 460
458 // Common specialized accessors for the fpreg() template. 461 // Common specialized accessors for the fpreg() template.
459 float sreg(unsigned code) const { 462 float sreg(unsigned code) const {
460 return fpreg<float>(code); 463 return fpreg<float>(code);
461 } 464 }
462 465
463 uint32_t sreg_bits(unsigned code) const { 466 uint32_t sreg_bits(unsigned code) const {
464 return fpreg<uint32_t>(code); 467 return fpreg<uint32_t>(code);
465 } 468 }
(...skipping 15 matching lines...) Expand all
481 return 0.0; 484 return 0.0;
482 } 485 }
483 } 486 }
484 487
485 // Write 'value' into a floating-point register. The value is zero-extended. 488 // Write 'value' into a floating-point register. The value is zero-extended.
486 // This behaviour matches AArch64 register writes. 489 // This behaviour matches AArch64 register writes.
487 template<typename T> 490 template<typename T>
488 void set_fpreg(unsigned code, T value) { 491 void set_fpreg(unsigned code, T value) {
489 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); 492 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize));
490 ASSERT(code < kNumberOfFPRegisters); 493 ASSERT(code < kNumberOfFPRegisters);
491 fpregisters_[code].Set(value, sizeof(value)); 494 fpregisters_[code].Set(value);
492 } 495 }
493 496
494 // Common specialized accessors for the set_fpreg() template. 497 // Common specialized accessors for the set_fpreg() template.
495 void set_sreg(unsigned code, float value) { 498 void set_sreg(unsigned code, float value) {
496 set_fpreg(code, value); 499 set_fpreg(code, value);
497 } 500 }
498 501
499 void set_sreg_bits(unsigned code, uint32_t value) { 502 void set_sreg_bits(unsigned code, uint32_t value) {
500 set_fpreg(code, value); 503 set_fpreg(code, value);
501 } 504 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 float MemoryReadFP32(uint8_t* address); 658 float MemoryReadFP32(uint8_t* address);
656 uint64_t MemoryRead64(uint8_t* address); 659 uint64_t MemoryRead64(uint8_t* address);
657 double MemoryReadFP64(uint8_t* address); 660 double MemoryReadFP64(uint8_t* address);
658 661
659 void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes); 662 void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes);
660 void MemoryWrite32(uint8_t* address, uint32_t value); 663 void MemoryWrite32(uint8_t* address, uint32_t value);
661 void MemoryWriteFP32(uint8_t* address, float value); 664 void MemoryWriteFP32(uint8_t* address, float value);
662 void MemoryWrite64(uint8_t* address, uint64_t value); 665 void MemoryWrite64(uint8_t* address, uint64_t value);
663 void MemoryWriteFP64(uint8_t* address, double value); 666 void MemoryWriteFP64(uint8_t* address, double value);
664 667
665 int64_t ShiftOperand(unsigned reg_size, 668
666 int64_t value, 669 template <typename T>
667 Shift shift_type, 670 T ShiftOperand(T value,
668 unsigned amount); 671 Shift shift_type,
672 unsigned amount);
673
674 template <typename T>
675 void DataProcessing2Source(Instruction* instr);
676
669 int64_t Rotate(unsigned reg_width, 677 int64_t Rotate(unsigned reg_width,
670 int64_t value, 678 int64_t value,
671 Shift shift_type, 679 Shift shift_type,
672 unsigned amount); 680 unsigned amount);
673 int64_t ExtendValue(unsigned reg_width, 681 int64_t ExtendValue(unsigned reg_width,
674 int64_t value, 682 int64_t value,
675 Extend extend_type, 683 Extend extend_type,
676 unsigned left_shift = 0); 684 unsigned left_shift = 0);
677 685
678 uint64_t ReverseBits(uint64_t value, unsigned num_bits); 686 uint64_t ReverseBits(uint64_t value, unsigned num_bits);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 static void UnregisterCTryCatch() { 888 static void UnregisterCTryCatch() {
881 Simulator::current(Isolate::Current())->PopAddress(); 889 Simulator::current(Isolate::Current())->PopAddress();
882 } 890 }
883 }; 891 };
884 892
885 #endif // !defined(USE_SIMULATOR) 893 #endif // !defined(USE_SIMULATOR)
886 894
887 } } // namespace v8::internal 895 } } // namespace v8::internal
888 896
889 #endif // V8_ARM64_SIMULATOR_ARM64_H_ 897 #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