e4d9a81ffdbe3d04305726efa911a83a8faaea37
[platform/upstream/v8.git] / src / arm64 / simulator-arm64.h
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
3 // found in the LICENSE file.
4
5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_
6 #define V8_ARM64_SIMULATOR_ARM64_H_
7
8 #include <stdarg.h>
9 #include <vector>
10
11 #include "src/allocation.h"
12 #include "src/arm64/assembler-arm64.h"
13 #include "src/arm64/decoder-arm64.h"
14 #include "src/arm64/disasm-arm64.h"
15 #include "src/arm64/instrument-arm64.h"
16 #include "src/assembler.h"
17 #include "src/globals.h"
18 #include "src/utils.h"
19
20 #define REGISTER_CODE_LIST(R)                                                  \
21 R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
22 R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
23 R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
24 R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
25
26 namespace v8 {
27 namespace internal {
28
29 #if !defined(USE_SIMULATOR)
30
31 // Running without a simulator on a native ARM64 platform.
32 // When running without a simulator we call the entry directly.
33 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
34   (entry(p0, p1, p2, p3, p4))
35
36 typedef int (*arm64_regexp_matcher)(String* input,
37                                     int64_t start_offset,
38                                     const byte* input_start,
39                                     const byte* input_end,
40                                     int* output,
41                                     int64_t output_size,
42                                     Address stack_base,
43                                     int64_t direct_call,
44                                     void* return_address,
45                                     Isolate* isolate);
46
47 // Call the generated regexp code directly. The code at the entry address
48 // should act as a function matching the type arm64_regexp_matcher.
49 // The ninth argument is a dummy that reserves the space used for
50 // the return address added by the ExitFrame in native calls.
51 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
52   (FUNCTION_CAST<arm64_regexp_matcher>(entry)(                                \
53       p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
54
55 // Running without a simulator there is nothing to do.
56 class SimulatorStack : public v8::internal::AllStatic {
57  public:
58   static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
59                                             uintptr_t c_limit) {
60     USE(isolate);
61     return c_limit;
62   }
63
64   static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
65     return try_catch_address;
66   }
67
68   static void UnregisterCTryCatch() { }
69 };
70
71 #else  // !defined(USE_SIMULATOR)
72
73
74 // The proper way to initialize a simulated system register (such as NZCV) is as
75 // follows:
76 //  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
77 class SimSystemRegister {
78  public:
79   // The default constructor represents a register which has no writable bits.
80   // It is not possible to set its value to anything other than 0.
81   SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { }
82
83   uint32_t RawValue() const {
84     return value_;
85   }
86
87   void SetRawValue(uint32_t new_value) {
88     value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
89   }
90
91   uint32_t Bits(int msb, int lsb) const {
92     return unsigned_bitextract_32(msb, lsb, value_);
93   }
94
95   int32_t SignedBits(int msb, int lsb) const {
96     return signed_bitextract_32(msb, lsb, value_);
97   }
98
99   void SetBits(int msb, int lsb, uint32_t bits);
100
101   // Default system register values.
102   static SimSystemRegister DefaultValueFor(SystemRegister id);
103
104 #define DEFINE_GETTER(Name, HighBit, LowBit, Func, Type)                       \
105   Type Name() const { return static_cast<Type>(Func(HighBit, LowBit)); }       \
106   void Set##Name(Type bits) {                                                  \
107     SetBits(HighBit, LowBit, static_cast<Type>(bits));                         \
108   }
109 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask)                                   \
110   static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
111   SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
112 #undef DEFINE_ZERO_BITS
113 #undef DEFINE_GETTER
114
115  protected:
116   // Most system registers only implement a few of the bits in the word. Other
117   // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
118   // describes the bits which are not modifiable.
119   SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
120       : value_(value), write_ignore_mask_(write_ignore_mask) { }
121
122   uint32_t value_;
123   uint32_t write_ignore_mask_;
124 };
125
126
127 // Represent a register (r0-r31, v0-v31).
128 class SimRegisterBase {
129  public:
130   template<typename T>
131   void Set(T new_value) {
132     value_ = 0;
133     memcpy(&value_, &new_value, sizeof(T));
134   }
135
136   template<typename T>
137   T Get() const {
138     T result;
139     memcpy(&result, &value_, sizeof(T));
140     return result;
141   }
142
143  protected:
144   int64_t value_;
145 };
146
147
148 typedef SimRegisterBase SimRegister;      // r0-r31
149 typedef SimRegisterBase SimFPRegister;    // v0-v31
150
151
152 class Simulator : public DecoderVisitor {
153  public:
154   static void FlushICache(v8::internal::HashMap* i_cache, void* start,
155                           size_t size) {
156     USE(i_cache);
157     USE(start);
158     USE(size);
159   }
160
161   explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
162                      Isolate* isolate = NULL,
163                      FILE* stream = stderr);
164   Simulator();
165   ~Simulator();
166
167   // System functions.
168
169   static void Initialize(Isolate* isolate);
170
171   static void TearDown(HashMap* i_cache, Redirection* first);
172
173   static Simulator* current(v8::internal::Isolate* isolate);
174
175   class CallArgument;
176
177   // Call an arbitrary function taking an arbitrary number of arguments. The
178   // varargs list must be a set of arguments with type CallArgument, and
179   // terminated by CallArgument::End().
180   void CallVoid(byte* entry, CallArgument* args);
181
182   // Like CallVoid, but expect a return value.
183   int64_t CallInt64(byte* entry, CallArgument* args);
184   double CallDouble(byte* entry, CallArgument* args);
185
186   // V8 calls into generated JS code with 5 parameters and into
187   // generated RegExp code with 10 parameters. These are convenience functions,
188   // which set up the simulator state and grab the result on return.
189   int64_t CallJS(byte* entry,
190                  Object* new_target,
191                  Object* target,
192                  Object* revc,
193                  int64_t argc,
194                  Object*** argv);
195   int64_t CallRegExp(byte* entry,
196                      String* input,
197                      int64_t start_offset,
198                      const byte* input_start,
199                      const byte* input_end,
200                      int* output,
201                      int64_t output_size,
202                      Address stack_base,
203                      int64_t direct_call,
204                      void* return_address,
205                      Isolate* isolate);
206
207   // A wrapper class that stores an argument for one of the above Call
208   // functions.
209   //
210   // Only arguments up to 64 bits in size are supported.
211   class CallArgument {
212    public:
213     template<typename T>
214     explicit CallArgument(T argument) {
215       bits_ = 0;
216       DCHECK(sizeof(argument) <= sizeof(bits_));
217       memcpy(&bits_, &argument, sizeof(argument));
218       type_ = X_ARG;
219     }
220
221     explicit CallArgument(double argument) {
222       DCHECK(sizeof(argument) == sizeof(bits_));
223       memcpy(&bits_, &argument, sizeof(argument));
224       type_ = D_ARG;
225     }
226
227     explicit CallArgument(float argument) {
228       // TODO(all): CallArgument(float) is untested, remove this check once
229       //            tested.
230       UNIMPLEMENTED();
231       // Make the D register a NaN to try to trap errors if the callee expects a
232       // double. If it expects a float, the callee should ignore the top word.
233       DCHECK(sizeof(kFP64SignallingNaN) == sizeof(bits_));
234       memcpy(&bits_, &kFP64SignallingNaN, sizeof(kFP64SignallingNaN));
235       // Write the float payload to the S register.
236       DCHECK(sizeof(argument) <= sizeof(bits_));
237       memcpy(&bits_, &argument, sizeof(argument));
238       type_ = D_ARG;
239     }
240
241     // This indicates the end of the arguments list, so that CallArgument
242     // objects can be passed into varargs functions.
243     static CallArgument End() { return CallArgument(); }
244
245     int64_t bits() const { return bits_; }
246     bool IsEnd() const { return type_ == NO_ARG; }
247     bool IsX() const { return type_ == X_ARG; }
248     bool IsD() const { return type_ == D_ARG; }
249
250    private:
251     enum CallArgumentType { X_ARG, D_ARG, NO_ARG };
252
253     // All arguments are aligned to at least 64 bits and we don't support
254     // passing bigger arguments, so the payload size can be fixed at 64 bits.
255     int64_t bits_;
256     CallArgumentType type_;
257
258     CallArgument() { type_ = NO_ARG; }
259   };
260
261
262   // Start the debugging command line.
263   void Debug();
264
265   bool GetValue(const char* desc, int64_t* value);
266
267   bool PrintValue(const char* desc);
268
269   // Push an address onto the JS stack.
270   uintptr_t PushAddress(uintptr_t address);
271
272   // Pop an address from the JS stack.
273   uintptr_t PopAddress();
274
275   // Accessor to the internal simulator stack area.
276   uintptr_t StackLimit(uintptr_t c_limit) const;
277
278   void ResetState();
279
280   // Runtime call support.
281   static void* RedirectExternalReference(void* external_function,
282                                          ExternalReference::Type type);
283   void DoRuntimeCall(Instruction* instr);
284
285   // Run the simulator.
286   static const Instruction* kEndOfSimAddress;
287   void DecodeInstruction();
288   void Run();
289   void RunFrom(Instruction* start);
290
291   // Simulation helpers.
292   template <typename T>
293   void set_pc(T new_pc) {
294     DCHECK(sizeof(T) == sizeof(pc_));
295     memcpy(&pc_, &new_pc, sizeof(T));
296     pc_modified_ = true;
297   }
298   Instruction* pc() { return pc_; }
299
300   void increment_pc() {
301     if (!pc_modified_) {
302       pc_ = pc_->following();
303     }
304
305     pc_modified_ = false;
306   }
307
308   virtual void Decode(Instruction* instr) {
309     decoder_->Decode(instr);
310   }
311
312   void ExecuteInstruction() {
313     DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize));
314     CheckBreakNext();
315     Decode(pc_);
316     increment_pc();
317     CheckBreakpoints();
318   }
319
320   // Declare all Visitor functions.
321   #define DECLARE(A)  void Visit##A(Instruction* instr);
322   VISITOR_LIST(DECLARE)
323   #undef DECLARE
324
325   bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const {
326     return ((code == 31) && (r31mode == Reg31IsZeroRegister));
327   }
328
329   // Register accessors.
330   // Return 'size' bits of the value of an integer register, as the specified
331   // type. The value is zero-extended to fill the result.
332   //
333   template<typename T>
334   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
335     DCHECK(code < kNumberOfRegisters);
336     if (IsZeroRegister(code, r31mode)) {
337       return 0;
338     }
339     return registers_[code].Get<T>();
340   }
341
342   // Common specialized accessors for the reg() template.
343   int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
344     return reg<int32_t>(code, r31mode);
345   }
346
347   int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
348     return reg<int64_t>(code, r31mode);
349   }
350
351   // Write 'value' into an integer register. The value is zero-extended. This
352   // behaviour matches AArch64 register writes.
353   template<typename T>
354   void set_reg(unsigned code, T value,
355                Reg31Mode r31mode = Reg31IsZeroRegister) {
356     set_reg_no_log(code, value, r31mode);
357     LogRegister(code, r31mode);
358   }
359
360   // Common specialized accessors for the set_reg() template.
361   void set_wreg(unsigned code, int32_t value,
362                 Reg31Mode r31mode = Reg31IsZeroRegister) {
363     set_reg(code, value, r31mode);
364   }
365
366   void set_xreg(unsigned code, int64_t value,
367                 Reg31Mode r31mode = Reg31IsZeroRegister) {
368     set_reg(code, value, r31mode);
369   }
370
371   // As above, but don't automatically log the register update.
372   template <typename T>
373   void set_reg_no_log(unsigned code, T value,
374                       Reg31Mode r31mode = Reg31IsZeroRegister) {
375     DCHECK(code < kNumberOfRegisters);
376     if (!IsZeroRegister(code, r31mode)) {
377       registers_[code].Set(value);
378     }
379   }
380
381   void set_wreg_no_log(unsigned code, int32_t value,
382                        Reg31Mode r31mode = Reg31IsZeroRegister) {
383     set_reg_no_log(code, value, r31mode);
384   }
385
386   void set_xreg_no_log(unsigned code, int64_t value,
387                        Reg31Mode r31mode = Reg31IsZeroRegister) {
388     set_reg_no_log(code, value, r31mode);
389   }
390
391   // Commonly-used special cases.
392   template<typename T>
393   void set_lr(T value) {
394     DCHECK(sizeof(T) == kPointerSize);
395     set_reg(kLinkRegCode, value);
396   }
397
398   template<typename T>
399   void set_sp(T value) {
400     DCHECK(sizeof(T) == kPointerSize);
401     set_reg(31, value, Reg31IsStackPointer);
402   }
403
404   int64_t sp() { return xreg(31, Reg31IsStackPointer); }
405   int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); }
406   int64_t fp() {
407       return xreg(kFramePointerRegCode, Reg31IsStackPointer);
408   }
409   Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
410
411   Address get_sp() const { return reg<Address>(31, Reg31IsStackPointer); }
412
413   template<typename T>
414   T fpreg(unsigned code) const {
415     DCHECK(code < kNumberOfRegisters);
416     return fpregisters_[code].Get<T>();
417   }
418
419   // Common specialized accessors for the fpreg() template.
420   float sreg(unsigned code) const {
421     return fpreg<float>(code);
422   }
423
424   uint32_t sreg_bits(unsigned code) const {
425     return fpreg<uint32_t>(code);
426   }
427
428   double dreg(unsigned code) const {
429     return fpreg<double>(code);
430   }
431
432   uint64_t dreg_bits(unsigned code) const {
433     return fpreg<uint64_t>(code);
434   }
435
436   double fpreg(unsigned size, unsigned code) const {
437     switch (size) {
438       case kSRegSizeInBits: return sreg(code);
439       case kDRegSizeInBits: return dreg(code);
440       default:
441         UNREACHABLE();
442         return 0.0;
443     }
444   }
445
446   // Write 'value' into a floating-point register. The value is zero-extended.
447   // This behaviour matches AArch64 register writes.
448   template<typename T>
449   void set_fpreg(unsigned code, T value) {
450     set_fpreg_no_log(code, value);
451
452     if (sizeof(value) <= kSRegSize) {
453       LogFPRegister(code, kPrintSRegValue);
454     } else {
455       LogFPRegister(code, kPrintDRegValue);
456     }
457   }
458
459   // Common specialized accessors for the set_fpreg() template.
460   void set_sreg(unsigned code, float value) {
461     set_fpreg(code, value);
462   }
463
464   void set_sreg_bits(unsigned code, uint32_t value) {
465     set_fpreg(code, value);
466   }
467
468   void set_dreg(unsigned code, double value) {
469     set_fpreg(code, value);
470   }
471
472   void set_dreg_bits(unsigned code, uint64_t value) {
473     set_fpreg(code, value);
474   }
475
476   // As above, but don't automatically log the register update.
477   template <typename T>
478   void set_fpreg_no_log(unsigned code, T value) {
479     DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize));
480     DCHECK(code < kNumberOfFPRegisters);
481     fpregisters_[code].Set(value);
482   }
483
484   void set_sreg_no_log(unsigned code, float value) {
485     set_fpreg_no_log(code, value);
486   }
487
488   void set_dreg_no_log(unsigned code, double value) {
489     set_fpreg_no_log(code, value);
490   }
491
492   SimSystemRegister& nzcv() { return nzcv_; }
493   SimSystemRegister& fpcr() { return fpcr_; }
494
495   // Debug helpers
496
497   // Simulator breakpoints.
498   struct Breakpoint {
499     Instruction* location;
500     bool enabled;
501   };
502   std::vector<Breakpoint> breakpoints_;
503   void SetBreakpoint(Instruction* breakpoint);
504   void ListBreakpoints();
505   void CheckBreakpoints();
506
507   // Helpers for the 'next' command.
508   // When this is set, the Simulator will insert a breakpoint after the next BL
509   // instruction it meets.
510   bool break_on_next_;
511   // Check if the Simulator should insert a break after the current instruction
512   // for the 'next' command.
513   void CheckBreakNext();
514
515   // Disassemble instruction at the given address.
516   void PrintInstructionsAt(Instruction* pc, uint64_t count);
517
518   // Print all registers of the specified types.
519   void PrintRegisters();
520   void PrintFPRegisters();
521   void PrintSystemRegisters();
522
523   // Like Print* (above), but respect log_parameters().
524   void LogSystemRegisters() {
525     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters();
526   }
527   void LogRegisters() {
528     if (log_parameters() & LOG_REGS) PrintRegisters();
529   }
530   void LogFPRegisters() {
531     if (log_parameters() & LOG_FP_REGS) PrintFPRegisters();
532   }
533
534   // Specify relevant register sizes, for PrintFPRegister.
535   //
536   // These values are bit masks; they can be combined in case multiple views of
537   // a machine register are interesting.
538   enum PrintFPRegisterSizes {
539     kPrintDRegValue = 1 << kDRegSize,
540     kPrintSRegValue = 1 << kSRegSize,
541     kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue
542   };
543
544   // Print individual register values (after update).
545   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
546   void PrintFPRegister(unsigned code,
547                        PrintFPRegisterSizes sizes = kPrintAllFPRegValues);
548   void PrintSystemRegister(SystemRegister id);
549
550   // Like Print* (above), but respect log_parameters().
551   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
552     if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode);
553   }
554   void LogFPRegister(unsigned code,
555                      PrintFPRegisterSizes sizes = kPrintAllFPRegValues) {
556     if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes);
557   }
558   void LogSystemRegister(SystemRegister id) {
559     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id);
560   }
561
562   // Print memory accesses.
563   void PrintRead(uintptr_t address, size_t size, unsigned reg_code);
564   void PrintReadFP(uintptr_t address, size_t size, unsigned reg_code);
565   void PrintWrite(uintptr_t address, size_t size, unsigned reg_code);
566   void PrintWriteFP(uintptr_t address, size_t size, unsigned reg_code);
567
568   // Like Print* (above), but respect log_parameters().
569   void LogRead(uintptr_t address, size_t size, unsigned reg_code) {
570     if (log_parameters() & LOG_REGS) PrintRead(address, size, reg_code);
571   }
572   void LogReadFP(uintptr_t address, size_t size, unsigned reg_code) {
573     if (log_parameters() & LOG_FP_REGS) PrintReadFP(address, size, reg_code);
574   }
575   void LogWrite(uintptr_t address, size_t size, unsigned reg_code) {
576     if (log_parameters() & LOG_WRITE) PrintWrite(address, size, reg_code);
577   }
578   void LogWriteFP(uintptr_t address, size_t size, unsigned reg_code) {
579     if (log_parameters() & LOG_WRITE) PrintWriteFP(address, size, reg_code);
580   }
581
582   int log_parameters() { return log_parameters_; }
583   void set_log_parameters(int new_parameters) {
584     log_parameters_ = new_parameters;
585     if (!decoder_) {
586       if (new_parameters & LOG_DISASM) {
587         PrintF("Run --debug-sim to dynamically turn on disassembler\n");
588       }
589       return;
590     }
591     if (new_parameters & LOG_DISASM) {
592       decoder_->InsertVisitorBefore(print_disasm_, this);
593     } else {
594       decoder_->RemoveVisitor(print_disasm_);
595     }
596   }
597
598   static inline const char* WRegNameForCode(unsigned code,
599       Reg31Mode mode = Reg31IsZeroRegister);
600   static inline const char* XRegNameForCode(unsigned code,
601       Reg31Mode mode = Reg31IsZeroRegister);
602   static inline const char* SRegNameForCode(unsigned code);
603   static inline const char* DRegNameForCode(unsigned code);
604   static inline const char* VRegNameForCode(unsigned code);
605   static inline int CodeFromName(const char* name);
606
607  protected:
608   // Simulation helpers ------------------------------------
609   bool ConditionPassed(Condition cond) {
610     SimSystemRegister& flags = nzcv();
611     switch (cond) {
612       case eq:
613         return flags.Z();
614       case ne:
615         return !flags.Z();
616       case hs:
617         return flags.C();
618       case lo:
619         return !flags.C();
620       case mi:
621         return flags.N();
622       case pl:
623         return !flags.N();
624       case vs:
625         return flags.V();
626       case vc:
627         return !flags.V();
628       case hi:
629         return flags.C() && !flags.Z();
630       case ls:
631         return !(flags.C() && !flags.Z());
632       case ge:
633         return flags.N() == flags.V();
634       case lt:
635         return flags.N() != flags.V();
636       case gt:
637         return !flags.Z() && (flags.N() == flags.V());
638       case le:
639         return !(!flags.Z() && (flags.N() == flags.V()));
640       case nv:  // Fall through.
641       case al:
642         return true;
643       default:
644         UNREACHABLE();
645         return false;
646     }
647   }
648
649   bool ConditionFailed(Condition cond) {
650     return !ConditionPassed(cond);
651   }
652
653   template<typename T>
654   void AddSubHelper(Instruction* instr, T op2);
655   template<typename T>
656   T AddWithCarry(bool set_flags,
657                  T src1,
658                  T src2,
659                  T carry_in = 0);
660   template<typename T>
661   void AddSubWithCarry(Instruction* instr);
662   template<typename T>
663   void LogicalHelper(Instruction* instr, T op2);
664   template<typename T>
665   void ConditionalCompareHelper(Instruction* instr, T op2);
666   void LoadStoreHelper(Instruction* instr,
667                        int64_t offset,
668                        AddrMode addrmode);
669   void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
670   uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset,
671                              AddrMode addrmode);
672   void LoadStoreWriteBack(unsigned addr_reg,
673                           int64_t offset,
674                           AddrMode addrmode);
675   void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
676
677   // Memory read helpers.
678   template <typename T, typename A>
679   T MemoryRead(A address) {
680     T value;
681     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
682                   (sizeof(value) == 4) || (sizeof(value) == 8));
683     memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value));
684     return value;
685   }
686
687   // Memory write helpers.
688   template <typename T, typename A>
689   void MemoryWrite(A address, T value) {
690     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
691                   (sizeof(value) == 4) || (sizeof(value) == 8));
692     memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
693   }
694
695   template <typename T>
696   T ShiftOperand(T value,
697                  Shift shift_type,
698                  unsigned amount);
699   template <typename T>
700   T ExtendValue(T value,
701                 Extend extend_type,
702                 unsigned left_shift = 0);
703   template <typename T>
704   void Extract(Instruction* instr);
705   template <typename T>
706   void DataProcessing2Source(Instruction* instr);
707   template <typename T>
708   void BitfieldHelper(Instruction* instr);
709
710   template <typename T>
711   T FPDefaultNaN() const;
712
713   void FPCompare(double val0, double val1);
714   double FPRoundInt(double value, FPRounding round_mode);
715   double FPToDouble(float value);
716   float FPToFloat(double value, FPRounding round_mode);
717   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
718   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
719   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
720   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
721   int32_t FPToInt32(double value, FPRounding rmode);
722   int64_t FPToInt64(double value, FPRounding rmode);
723   uint32_t FPToUInt32(double value, FPRounding rmode);
724   uint64_t FPToUInt64(double value, FPRounding rmode);
725
726   template <typename T>
727   T FPAdd(T op1, T op2);
728
729   template <typename T>
730   T FPDiv(T op1, T op2);
731
732   template <typename T>
733   T FPMax(T a, T b);
734
735   template <typename T>
736   T FPMaxNM(T a, T b);
737
738   template <typename T>
739   T FPMin(T a, T b);
740
741   template <typename T>
742   T FPMinNM(T a, T b);
743
744   template <typename T>
745   T FPMul(T op1, T op2);
746
747   template <typename T>
748   T FPMulAdd(T a, T op1, T op2);
749
750   template <typename T>
751   T FPSqrt(T op);
752
753   template <typename T>
754   T FPSub(T op1, T op2);
755
756   // Standard NaN processing.
757   template <typename T>
758   T FPProcessNaN(T op);
759
760   bool FPProcessNaNs(Instruction* instr);
761
762   template <typename T>
763   T FPProcessNaNs(T op1, T op2);
764
765   template <typename T>
766   T FPProcessNaNs3(T op1, T op2, T op3);
767
768   void CheckStackAlignment();
769
770   inline void CheckPCSComplianceAndRun();
771
772 #ifdef DEBUG
773   // Corruption values should have their least significant byte cleared to
774   // allow the code of the register being corrupted to be inserted.
775   static const uint64_t kCallerSavedRegisterCorruptionValue =
776       0xca11edc0de000000UL;
777   // This value is a NaN in both 32-bit and 64-bit FP.
778   static const uint64_t kCallerSavedFPRegisterCorruptionValue =
779       0x7ff000007f801000UL;
780   // This value is a mix of 32/64-bits NaN and "verbose" immediate.
781   static const uint64_t kDefaultCPURegisterCorruptionValue =
782       0x7ffbad007f8bad00UL;
783
784   void CorruptRegisters(CPURegList* list,
785                         uint64_t value = kDefaultCPURegisterCorruptionValue);
786   void CorruptAllCallerSavedCPURegisters();
787 #endif
788
789   // Pseudo Printf instruction
790   void DoPrintf(Instruction* instr);
791
792   // Processor state ---------------------------------------
793
794   // Output stream.
795   FILE* stream_;
796   PrintDisassembler* print_disasm_;
797   void PRINTF_METHOD_CHECKING TraceSim(const char* format, ...);
798
799   // Instrumentation.
800   Instrument* instrument_;
801
802   // General purpose registers. Register 31 is the stack pointer.
803   SimRegister registers_[kNumberOfRegisters];
804
805   // Floating point registers
806   SimFPRegister fpregisters_[kNumberOfFPRegisters];
807
808   // Processor state
809   // bits[31, 27]: Condition flags N, Z, C, and V.
810   //               (Negative, Zero, Carry, Overflow)
811   SimSystemRegister nzcv_;
812
813   // Floating-Point Control Register
814   SimSystemRegister fpcr_;
815
816   // Only a subset of FPCR features are supported by the simulator. This helper
817   // checks that the FPCR settings are supported.
818   //
819   // This is checked when floating-point instructions are executed, not when
820   // FPCR is set. This allows generated code to modify FPCR for external
821   // functions, or to save and restore it when entering and leaving generated
822   // code.
823   void AssertSupportedFPCR() {
824     DCHECK(fpcr().FZ() == 0);             // No flush-to-zero support.
825     DCHECK(fpcr().RMode() == FPTieEven);  // Ties-to-even rounding only.
826
827     // The simulator does not support half-precision operations so fpcr().AHP()
828     // is irrelevant, and is not checked here.
829   }
830
831   template <typename T>
832   static int CalcNFlag(T result) {
833     return (result >> (sizeof(T) * 8 - 1)) & 1;
834   }
835
836   static int CalcZFlag(uint64_t result) {
837     return result == 0;
838   }
839
840   static const uint32_t kConditionFlagsMask = 0xf0000000;
841
842   // Stack
843   uintptr_t stack_;
844   static const size_t stack_protection_size_ = KB;
845   size_t stack_size_;
846   uintptr_t stack_limit_;
847
848   Decoder<DispatchingDecoderVisitor>* decoder_;
849   Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
850
851   // Indicates if the pc has been modified by the instruction and should not be
852   // automatically incremented.
853   bool pc_modified_;
854   Instruction* pc_;
855
856   static const char* xreg_names[];
857   static const char* wreg_names[];
858   static const char* sreg_names[];
859   static const char* dreg_names[];
860   static const char* vreg_names[];
861
862   // Debugger input.
863   void set_last_debugger_input(char* input) {
864     DeleteArray(last_debugger_input_);
865     last_debugger_input_ = input;
866   }
867   char* last_debugger_input() { return last_debugger_input_; }
868   char* last_debugger_input_;
869
870  private:
871   void Init(FILE* stream);
872
873   int  log_parameters_;
874   Isolate* isolate_;
875 };
876
877
878 // When running with the simulator transition into simulated execution at this
879 // point.
880 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
881   reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->CallJS(    \
882       FUNCTION_ADDR(entry),                                                    \
883       p0, p1, p2, p3, p4))
884
885 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
886   static_cast<int>(                                                           \
887       Simulator::current(Isolate::Current())                                  \
888           ->CallRegExp(entry, p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
889
890
891 // The simulator has its own stack. Thus it has a different stack limit from
892 // the C-based native code.  The JS-based limit normally points near the end of
893 // the simulator stack.  When the C-based limit is exhausted we reflect that by
894 // lowering the JS-based limit as well, to make stack checks trigger.
895 class SimulatorStack : public v8::internal::AllStatic {
896  public:
897   static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
898                                             uintptr_t c_limit) {
899     return Simulator::current(isolate)->StackLimit(c_limit);
900   }
901
902   static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
903     Simulator* sim = Simulator::current(Isolate::Current());
904     return sim->PushAddress(try_catch_address);
905   }
906
907   static void UnregisterCTryCatch() {
908     Simulator::current(Isolate::Current())->PopAddress();
909   }
910 };
911
912 #endif  // !defined(USE_SIMULATOR)
913
914 } }  // namespace v8::internal
915
916 #endif  // V8_ARM64_SIMULATOR_ARM64_H_