Home | History | Annotate | Download | only in arm64
      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/base/compiler-specific.h"
     18 #include "src/globals.h"
     19 #include "src/utils.h"
     20 
     21 namespace v8 {
     22 namespace internal {
     23 
     24 #if !defined(USE_SIMULATOR)
     25 
     26 // Running without a simulator on a native ARM64 platform.
     27 // When running without a simulator we call the entry directly.
     28 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
     29   (entry(p0, p1, p2, p3, p4))
     30 
     31 typedef int (*arm64_regexp_matcher)(String* input,
     32                                     int64_t start_offset,
     33                                     const byte* input_start,
     34                                     const byte* input_end,
     35                                     int* output,
     36                                     int64_t output_size,
     37                                     Address stack_base,
     38                                     int64_t direct_call,
     39                                     void* return_address,
     40                                     Isolate* isolate);
     41 
     42 // Call the generated regexp code directly. The code at the entry address
     43 // should act as a function matching the type arm64_regexp_matcher.
     44 // The ninth argument is a dummy that reserves the space used for
     45 // the return address added by the ExitFrame in native calls.
     46 #define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
     47                                    p7, p8)                                     \
     48   (FUNCTION_CAST<arm64_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7,  \
     49                                               NULL, p8))
     50 
     51 // Running without a simulator there is nothing to do.
     52 class SimulatorStack : public v8::internal::AllStatic {
     53  public:
     54   static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
     55                                      uintptr_t c_limit) {
     56     USE(isolate);
     57     return c_limit;
     58   }
     59 
     60   static uintptr_t RegisterCTryCatch(v8::internal::Isolate* isolate,
     61                                      uintptr_t try_catch_address) {
     62     USE(isolate);
     63     return try_catch_address;
     64   }
     65 
     66   static void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
     67     USE(isolate);
     68   }
     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(base::CustomMatcherHashMap* 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(base::CustomMatcherHashMap* 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(Isolate* isolate,
    282                                          void* external_function,
    283                                          ExternalReference::Type type);
    284   void DoRuntimeCall(Instruction* instr);
    285 
    286   // Run the simulator.
    287   static const Instruction* kEndOfSimAddress;
    288   void DecodeInstruction();
    289   void Run();
    290   void RunFrom(Instruction* start);
    291 
    292   // Simulation helpers.
    293   template <typename T>
    294   void set_pc(T new_pc) {
    295     DCHECK(sizeof(T) == sizeof(pc_));
    296     memcpy(&pc_, &new_pc, sizeof(T));
    297     pc_modified_ = true;
    298   }
    299   Instruction* pc() { return pc_; }
    300 
    301   void increment_pc() {
    302     if (!pc_modified_) {
    303       pc_ = pc_->following();
    304     }
    305 
    306     pc_modified_ = false;
    307   }
    308 
    309   virtual void Decode(Instruction* instr) {
    310     decoder_->Decode(instr);
    311   }
    312 
    313   void ExecuteInstruction() {
    314     DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize));
    315     CheckBreakNext();
    316     Decode(pc_);
    317     increment_pc();
    318     CheckBreakpoints();
    319   }
    320 
    321   // Declare all Visitor functions.
    322   #define DECLARE(A)  void Visit##A(Instruction* instr);
    323   VISITOR_LIST(DECLARE)
    324   #undef DECLARE
    325 
    326   bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const {
    327     return ((code == 31) && (r31mode == Reg31IsZeroRegister));
    328   }
    329 
    330   // Register accessors.
    331   // Return 'size' bits of the value of an integer register, as the specified
    332   // type. The value is zero-extended to fill the result.
    333   //
    334   template<typename T>
    335   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
    336     DCHECK(code < kNumberOfRegisters);
    337     if (IsZeroRegister(code, r31mode)) {
    338       return 0;
    339     }
    340     return registers_[code].Get<T>();
    341   }
    342 
    343   // Common specialized accessors for the reg() template.
    344   int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
    345     return reg<int32_t>(code, r31mode);
    346   }
    347 
    348   int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
    349     return reg<int64_t>(code, r31mode);
    350   }
    351 
    352   // Write 'value' into an integer register. The value is zero-extended. This
    353   // behaviour matches AArch64 register writes.
    354   template<typename T>
    355   void set_reg(unsigned code, T value,
    356                Reg31Mode r31mode = Reg31IsZeroRegister) {
    357     set_reg_no_log(code, value, r31mode);
    358     LogRegister(code, r31mode);
    359   }
    360 
    361   // Common specialized accessors for the set_reg() template.
    362   void set_wreg(unsigned code, int32_t value,
    363                 Reg31Mode r31mode = Reg31IsZeroRegister) {
    364     set_reg(code, value, r31mode);
    365   }
    366 
    367   void set_xreg(unsigned code, int64_t value,
    368                 Reg31Mode r31mode = Reg31IsZeroRegister) {
    369     set_reg(code, value, r31mode);
    370   }
    371 
    372   // As above, but don't automatically log the register update.
    373   template <typename T>
    374   void set_reg_no_log(unsigned code, T value,
    375                       Reg31Mode r31mode = Reg31IsZeroRegister) {
    376     DCHECK(code < kNumberOfRegisters);
    377     if (!IsZeroRegister(code, r31mode)) {
    378       registers_[code].Set(value);
    379     }
    380   }
    381 
    382   void set_wreg_no_log(unsigned code, int32_t value,
    383                        Reg31Mode r31mode = Reg31IsZeroRegister) {
    384     set_reg_no_log(code, value, r31mode);
    385   }
    386 
    387   void set_xreg_no_log(unsigned code, int64_t value,
    388                        Reg31Mode r31mode = Reg31IsZeroRegister) {
    389     set_reg_no_log(code, value, r31mode);
    390   }
    391 
    392   // Commonly-used special cases.
    393   template<typename T>
    394   void set_lr(T value) {
    395     DCHECK(sizeof(T) == kPointerSize);
    396     set_reg(kLinkRegCode, value);
    397   }
    398 
    399   template<typename T>
    400   void set_sp(T value) {
    401     DCHECK(sizeof(T) == kPointerSize);
    402     set_reg(31, value, Reg31IsStackPointer);
    403   }
    404 
    405   int64_t sp() { return xreg(31, Reg31IsStackPointer); }
    406   int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); }
    407   int64_t fp() {
    408       return xreg(kFramePointerRegCode, Reg31IsStackPointer);
    409   }
    410   Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
    411 
    412   Address get_sp() const { return reg<Address>(31, Reg31IsStackPointer); }
    413 
    414   template<typename T>
    415   T fpreg(unsigned code) const {
    416     DCHECK(code < kNumberOfRegisters);
    417     return fpregisters_[code].Get<T>();
    418   }
    419 
    420   // Common specialized accessors for the fpreg() template.
    421   float sreg(unsigned code) const {
    422     return fpreg<float>(code);
    423   }
    424 
    425   uint32_t sreg_bits(unsigned code) const {
    426     return fpreg<uint32_t>(code);
    427   }
    428 
    429   double dreg(unsigned code) const {
    430     return fpreg<double>(code);
    431   }
    432 
    433   uint64_t dreg_bits(unsigned code) const {
    434     return fpreg<uint64_t>(code);
    435   }
    436 
    437   double fpreg(unsigned size, unsigned code) const {
    438     switch (size) {
    439       case kSRegSizeInBits: return sreg(code);
    440       case kDRegSizeInBits: return dreg(code);
    441       default:
    442         UNREACHABLE();
    443         return 0.0;
    444     }
    445   }
    446 
    447   // Write 'value' into a floating-point register. The value is zero-extended.
    448   // This behaviour matches AArch64 register writes.
    449   template<typename T>
    450   void set_fpreg(unsigned code, T value) {
    451     set_fpreg_no_log(code, value);
    452 
    453     if (sizeof(value) <= kSRegSize) {
    454       LogFPRegister(code, kPrintSRegValue);
    455     } else {
    456       LogFPRegister(code, kPrintDRegValue);
    457     }
    458   }
    459 
    460   // Common specialized accessors for the set_fpreg() template.
    461   void set_sreg(unsigned code, float value) {
    462     set_fpreg(code, value);
    463   }
    464 
    465   void set_sreg_bits(unsigned code, uint32_t value) {
    466     set_fpreg(code, value);
    467   }
    468 
    469   void set_dreg(unsigned code, double value) {
    470     set_fpreg(code, value);
    471   }
    472 
    473   void set_dreg_bits(unsigned code, uint64_t value) {
    474     set_fpreg(code, value);
    475   }
    476 
    477   // As above, but don't automatically log the register update.
    478   template <typename T>
    479   void set_fpreg_no_log(unsigned code, T value) {
    480     DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize));
    481     DCHECK(code < kNumberOfFPRegisters);
    482     fpregisters_[code].Set(value);
    483   }
    484 
    485   void set_sreg_no_log(unsigned code, float value) {
    486     set_fpreg_no_log(code, value);
    487   }
    488 
    489   void set_dreg_no_log(unsigned code, double value) {
    490     set_fpreg_no_log(code, value);
    491   }
    492 
    493   SimSystemRegister& nzcv() { return nzcv_; }
    494   SimSystemRegister& fpcr() { return fpcr_; }
    495 
    496   // Debug helpers
    497 
    498   // Simulator breakpoints.
    499   struct Breakpoint {
    500     Instruction* location;
    501     bool enabled;
    502   };
    503   std::vector<Breakpoint> breakpoints_;
    504   void SetBreakpoint(Instruction* breakpoint);
    505   void ListBreakpoints();
    506   void CheckBreakpoints();
    507 
    508   // Helpers for the 'next' command.
    509   // When this is set, the Simulator will insert a breakpoint after the next BL
    510   // instruction it meets.
    511   bool break_on_next_;
    512   // Check if the Simulator should insert a break after the current instruction
    513   // for the 'next' command.
    514   void CheckBreakNext();
    515 
    516   // Disassemble instruction at the given address.
    517   void PrintInstructionsAt(Instruction* pc, uint64_t count);
    518 
    519   // Print all registers of the specified types.
    520   void PrintRegisters();
    521   void PrintFPRegisters();
    522   void PrintSystemRegisters();
    523 
    524   // Like Print* (above), but respect log_parameters().
    525   void LogSystemRegisters() {
    526     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters();
    527   }
    528   void LogRegisters() {
    529     if (log_parameters() & LOG_REGS) PrintRegisters();
    530   }
    531   void LogFPRegisters() {
    532     if (log_parameters() & LOG_FP_REGS) PrintFPRegisters();
    533   }
    534 
    535   // Specify relevant register sizes, for PrintFPRegister.
    536   //
    537   // These values are bit masks; they can be combined in case multiple views of
    538   // a machine register are interesting.
    539   enum PrintFPRegisterSizes {
    540     kPrintDRegValue = 1 << kDRegSize,
    541     kPrintSRegValue = 1 << kSRegSize,
    542     kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue
    543   };
    544 
    545   // Print individual register values (after update).
    546   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
    547   void PrintFPRegister(unsigned code,
    548                        PrintFPRegisterSizes sizes = kPrintAllFPRegValues);
    549   void PrintSystemRegister(SystemRegister id);
    550 
    551   // Like Print* (above), but respect log_parameters().
    552   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
    553     if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode);
    554   }
    555   void LogFPRegister(unsigned code,
    556                      PrintFPRegisterSizes sizes = kPrintAllFPRegValues) {
    557     if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes);
    558   }
    559   void LogSystemRegister(SystemRegister id) {
    560     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id);
    561   }
    562 
    563   // Print memory accesses.
    564   void PrintRead(uintptr_t address, size_t size, unsigned reg_code);
    565   void PrintReadFP(uintptr_t address, size_t size, unsigned reg_code);
    566   void PrintWrite(uintptr_t address, size_t size, unsigned reg_code);
    567   void PrintWriteFP(uintptr_t address, size_t size, unsigned reg_code);
    568 
    569   // Like Print* (above), but respect log_parameters().
    570   void LogRead(uintptr_t address, size_t size, unsigned reg_code) {
    571     if (log_parameters() & LOG_REGS) PrintRead(address, size, reg_code);
    572   }
    573   void LogReadFP(uintptr_t address, size_t size, unsigned reg_code) {
    574     if (log_parameters() & LOG_FP_REGS) PrintReadFP(address, size, reg_code);
    575   }
    576   void LogWrite(uintptr_t address, size_t size, unsigned reg_code) {
    577     if (log_parameters() & LOG_WRITE) PrintWrite(address, size, reg_code);
    578   }
    579   void LogWriteFP(uintptr_t address, size_t size, unsigned reg_code) {
    580     if (log_parameters() & LOG_WRITE) PrintWriteFP(address, size, reg_code);
    581   }
    582 
    583   int log_parameters() { return log_parameters_; }
    584   void set_log_parameters(int new_parameters) {
    585     log_parameters_ = new_parameters;
    586     if (!decoder_) {
    587       if (new_parameters & LOG_DISASM) {
    588         PrintF("Run --debug-sim to dynamically turn on disassembler\n");
    589       }
    590       return;
    591     }
    592     if (new_parameters & LOG_DISASM) {
    593       decoder_->InsertVisitorBefore(print_disasm_, this);
    594     } else {
    595       decoder_->RemoveVisitor(print_disasm_);
    596     }
    597   }
    598 
    599   static inline const char* WRegNameForCode(unsigned code,
    600       Reg31Mode mode = Reg31IsZeroRegister);
    601   static inline const char* XRegNameForCode(unsigned code,
    602       Reg31Mode mode = Reg31IsZeroRegister);
    603   static inline const char* SRegNameForCode(unsigned code);
    604   static inline const char* DRegNameForCode(unsigned code);
    605   static inline const char* VRegNameForCode(unsigned code);
    606   static inline int CodeFromName(const char* name);
    607 
    608  protected:
    609   // Simulation helpers ------------------------------------
    610   bool ConditionPassed(Condition cond) {
    611     SimSystemRegister& flags = nzcv();
    612     switch (cond) {
    613       case eq:
    614         return flags.Z();
    615       case ne:
    616         return !flags.Z();
    617       case hs:
    618         return flags.C();
    619       case lo:
    620         return !flags.C();
    621       case mi:
    622         return flags.N();
    623       case pl:
    624         return !flags.N();
    625       case vs:
    626         return flags.V();
    627       case vc:
    628         return !flags.V();
    629       case hi:
    630         return flags.C() && !flags.Z();
    631       case ls:
    632         return !(flags.C() && !flags.Z());
    633       case ge:
    634         return flags.N() == flags.V();
    635       case lt:
    636         return flags.N() != flags.V();
    637       case gt:
    638         return !flags.Z() && (flags.N() == flags.V());
    639       case le:
    640         return !(!flags.Z() && (flags.N() == flags.V()));
    641       case nv:  // Fall through.
    642       case al:
    643         return true;
    644       default:
    645         UNREACHABLE();
    646         return false;
    647     }
    648   }
    649 
    650   bool ConditionFailed(Condition cond) {
    651     return !ConditionPassed(cond);
    652   }
    653 
    654   template<typename T>
    655   void AddSubHelper(Instruction* instr, T op2);
    656   template <typename T>
    657   T AddWithCarry(bool set_flags, T left, T right, int carry_in = 0);
    658   template<typename T>
    659   void AddSubWithCarry(Instruction* instr);
    660   template<typename T>
    661   void LogicalHelper(Instruction* instr, T op2);
    662   template<typename T>
    663   void ConditionalCompareHelper(Instruction* instr, T op2);
    664   void LoadStoreHelper(Instruction* instr,
    665                        int64_t offset,
    666                        AddrMode addrmode);
    667   void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
    668   uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset,
    669                              AddrMode addrmode);
    670   void LoadStoreWriteBack(unsigned addr_reg,
    671                           int64_t offset,
    672                           AddrMode addrmode);
    673   void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
    674 
    675   // Memory read helpers.
    676   template <typename T, typename A>
    677   T MemoryRead(A address) {
    678     T value;
    679     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
    680                   (sizeof(value) == 4) || (sizeof(value) == 8));
    681     memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value));
    682     return value;
    683   }
    684 
    685   // Memory write helpers.
    686   template <typename T, typename A>
    687   void MemoryWrite(A address, T value) {
    688     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
    689                   (sizeof(value) == 4) || (sizeof(value) == 8));
    690     memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
    691   }
    692 
    693   template <typename T>
    694   T ShiftOperand(T value,
    695                  Shift shift_type,
    696                  unsigned amount);
    697   template <typename T>
    698   T ExtendValue(T value,
    699                 Extend extend_type,
    700                 unsigned left_shift = 0);
    701   template <typename T>
    702   void Extract(Instruction* instr);
    703   template <typename T>
    704   void DataProcessing2Source(Instruction* instr);
    705   template <typename T>
    706   void BitfieldHelper(Instruction* instr);
    707 
    708   template <typename T>
    709   T FPDefaultNaN() const;
    710 
    711   void FPCompare(double val0, double val1);
    712   double FPRoundInt(double value, FPRounding round_mode);
    713   double FPToDouble(float value);
    714   float FPToFloat(double value, FPRounding round_mode);
    715   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
    716   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
    717   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
    718   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
    719   int32_t FPToInt32(double value, FPRounding rmode);
    720   int64_t FPToInt64(double value, FPRounding rmode);
    721   uint32_t FPToUInt32(double value, FPRounding rmode);
    722   uint64_t FPToUInt64(double value, FPRounding rmode);
    723 
    724   template <typename T>
    725   T FPAdd(T op1, T op2);
    726 
    727   template <typename T>
    728   T FPDiv(T op1, T op2);
    729 
    730   template <typename T>
    731   T FPMax(T a, T b);
    732 
    733   template <typename T>
    734   T FPMaxNM(T a, T b);
    735 
    736   template <typename T>
    737   T FPMin(T a, T b);
    738 
    739   template <typename T>
    740   T FPMinNM(T a, T b);
    741 
    742   template <typename T>
    743   T FPMul(T op1, T op2);
    744 
    745   template <typename T>
    746   T FPMulAdd(T a, T op1, T op2);
    747 
    748   template <typename T>
    749   T FPSqrt(T op);
    750 
    751   template <typename T>
    752   T FPSub(T op1, T op2);
    753 
    754   // Standard NaN processing.
    755   template <typename T>
    756   T FPProcessNaN(T op);
    757 
    758   bool FPProcessNaNs(Instruction* instr);
    759 
    760   template <typename T>
    761   T FPProcessNaNs(T op1, T op2);
    762 
    763   template <typename T>
    764   T FPProcessNaNs3(T op1, T op2, T op3);
    765 
    766   void CheckStackAlignment();
    767 
    768   inline void CheckPCSComplianceAndRun();
    769 
    770 #ifdef DEBUG
    771   // Corruption values should have their least significant byte cleared to
    772   // allow the code of the register being corrupted to be inserted.
    773   static const uint64_t kCallerSavedRegisterCorruptionValue =
    774       0xca11edc0de000000UL;
    775   // This value is a NaN in both 32-bit and 64-bit FP.
    776   static const uint64_t kCallerSavedFPRegisterCorruptionValue =
    777       0x7ff000007f801000UL;
    778   // This value is a mix of 32/64-bits NaN and "verbose" immediate.
    779   static const uint64_t kDefaultCPURegisterCorruptionValue =
    780       0x7ffbad007f8bad00UL;
    781 
    782   void CorruptRegisters(CPURegList* list,
    783                         uint64_t value = kDefaultCPURegisterCorruptionValue);
    784   void CorruptAllCallerSavedCPURegisters();
    785 #endif
    786 
    787   // Pseudo Printf instruction
    788   void DoPrintf(Instruction* instr);
    789 
    790   // Processor state ---------------------------------------
    791 
    792   // Output stream.
    793   FILE* stream_;
    794   PrintDisassembler* print_disasm_;
    795   void PRINTF_FORMAT(2, 3) TraceSim(const char* format, ...);
    796 
    797   // Instrumentation.
    798   Instrument* instrument_;
    799 
    800   // General purpose registers. Register 31 is the stack pointer.
    801   SimRegister registers_[kNumberOfRegisters];
    802 
    803   // Floating point registers
    804   SimFPRegister fpregisters_[kNumberOfFPRegisters];
    805 
    806   // Processor state
    807   // bits[31, 27]: Condition flags N, Z, C, and V.
    808   //               (Negative, Zero, Carry, Overflow)
    809   SimSystemRegister nzcv_;
    810 
    811   // Floating-Point Control Register
    812   SimSystemRegister fpcr_;
    813 
    814   // Only a subset of FPCR features are supported by the simulator. This helper
    815   // checks that the FPCR settings are supported.
    816   //
    817   // This is checked when floating-point instructions are executed, not when
    818   // FPCR is set. This allows generated code to modify FPCR for external
    819   // functions, or to save and restore it when entering and leaving generated
    820   // code.
    821   void AssertSupportedFPCR() {
    822     DCHECK(fpcr().FZ() == 0);             // No flush-to-zero support.
    823     DCHECK(fpcr().RMode() == FPTieEven);  // Ties-to-even rounding only.
    824 
    825     // The simulator does not support half-precision operations so fpcr().AHP()
    826     // is irrelevant, and is not checked here.
    827   }
    828 
    829   template <typename T>
    830   static int CalcNFlag(T result) {
    831     return (result >> (sizeof(T) * 8 - 1)) & 1;
    832   }
    833 
    834   static int CalcZFlag(uint64_t result) {
    835     return result == 0;
    836   }
    837 
    838   static const uint32_t kConditionFlagsMask = 0xf0000000;
    839 
    840   // Stack
    841   uintptr_t stack_;
    842   static const size_t stack_protection_size_ = KB;
    843   size_t stack_size_;
    844   uintptr_t stack_limit_;
    845 
    846   Decoder<DispatchingDecoderVisitor>* decoder_;
    847   Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
    848 
    849   // Indicates if the pc has been modified by the instruction and should not be
    850   // automatically incremented.
    851   bool pc_modified_;
    852   Instruction* pc_;
    853 
    854   static const char* xreg_names[];
    855   static const char* wreg_names[];
    856   static const char* sreg_names[];
    857   static const char* dreg_names[];
    858   static const char* vreg_names[];
    859 
    860   // Debugger input.
    861   void set_last_debugger_input(char* input) {
    862     DeleteArray(last_debugger_input_);
    863     last_debugger_input_ = input;
    864   }
    865   char* last_debugger_input() { return last_debugger_input_; }
    866   char* last_debugger_input_;
    867 
    868  private:
    869   void Init(FILE* stream);
    870 
    871   int  log_parameters_;
    872   Isolate* isolate_;
    873 };
    874 
    875 
    876 // When running with the simulator transition into simulated execution at this
    877 // point.
    878 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4)  \
    879   reinterpret_cast<Object*>(Simulator::current(isolate)->CallJS( \
    880       FUNCTION_ADDR(entry), p0, p1, p2, p3, p4))
    881 
    882 #define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
    883                                    p7, p8)                                     \
    884   static_cast<int>(Simulator::current(isolate)->CallRegExp(                    \
    885       entry, p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
    886 
    887 
    888 // The simulator has its own stack. Thus it has a different stack limit from
    889 // the C-based native code.  The JS-based limit normally points near the end of
    890 // the simulator stack.  When the C-based limit is exhausted we reflect that by
    891 // lowering the JS-based limit as well, to make stack checks trigger.
    892 class SimulatorStack : public v8::internal::AllStatic {
    893  public:
    894   static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
    895                                             uintptr_t c_limit) {
    896     return Simulator::current(isolate)->StackLimit(c_limit);
    897   }
    898 
    899   static uintptr_t RegisterCTryCatch(v8::internal::Isolate* isolate,
    900                                      uintptr_t try_catch_address) {
    901     Simulator* sim = Simulator::current(isolate);
    902     return sim->PushAddress(try_catch_address);
    903   }
    904 
    905   static void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
    906     Simulator::current(isolate)->PopAddress();
    907   }
    908 };
    909 
    910 #endif  // !defined(USE_SIMULATOR)
    911 
    912 }  // namespace internal
    913 }  // namespace v8
    914 
    915 #endif  // V8_ARM64_SIMULATOR_ARM64_H_
    916