diff --git a/src/arm64/simulator-arm64.h b/src/arm64/simulator-arm64.h
new file mode 100644
index 0000000..108f6f2
--- /dev/null
+++ b/src/arm64/simulator-arm64.h
@@ -0,0 +1,917 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_ARM64_SIMULATOR_ARM64_H_
+#define V8_ARM64_SIMULATOR_ARM64_H_
+
+#include <stdarg.h>
+#include <vector>
+
+#include "src/v8.h"
+
+#include "src/allocation.h"
+#include "src/arm64/assembler-arm64.h"
+#include "src/arm64/decoder-arm64.h"
+#include "src/arm64/disasm-arm64.h"
+#include "src/arm64/instrument-arm64.h"
+#include "src/assembler.h"
+#include "src/globals.h"
+#include "src/utils.h"
+
+#define REGISTER_CODE_LIST(R)                                                  \
+R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
+R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
+R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
+R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
+
+namespace v8 {
+namespace internal {
+
+#if !defined(USE_SIMULATOR)
+
+// Running without a simulator on a native ARM64 platform.
+// When running without a simulator we call the entry directly.
+#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
+  (entry(p0, p1, p2, p3, p4))
+
+typedef int (*arm64_regexp_matcher)(String* input,
+                                    int64_t start_offset,
+                                    const byte* input_start,
+                                    const byte* input_end,
+                                    int* output,
+                                    int64_t output_size,
+                                    Address stack_base,
+                                    int64_t direct_call,
+                                    void* return_address,
+                                    Isolate* isolate);
+
+// Call the generated regexp code directly. The code at the entry address
+// should act as a function matching the type arm64_regexp_matcher.
+// The ninth argument is a dummy that reserves the space used for
+// the return address added by the ExitFrame in native calls.
+#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
+  (FUNCTION_CAST<arm64_regexp_matcher>(entry)(                                \
+      p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
+
+// Running without a simulator there is nothing to do.
+class SimulatorStack : public v8::internal::AllStatic {
+ public:
+  static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
+                                            uintptr_t c_limit) {
+    USE(isolate);
+    return c_limit;
+  }
+
+  static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
+    return try_catch_address;
+  }
+
+  static void UnregisterCTryCatch() { }
+};
+
+#else  // !defined(USE_SIMULATOR)
+
+enum ReverseByteMode {
+  Reverse16 = 0,
+  Reverse32 = 1,
+  Reverse64 = 2
+};
+
+
+// The proper way to initialize a simulated system register (such as NZCV) is as
+// follows:
+//  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
+class SimSystemRegister {
+ public:
+  // The default constructor represents a register which has no writable bits.
+  // It is not possible to set its value to anything other than 0.
+  SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { }
+
+  uint32_t RawValue() const {
+    return value_;
+  }
+
+  void SetRawValue(uint32_t new_value) {
+    value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
+  }
+
+  uint32_t Bits(int msb, int lsb) const {
+    return unsigned_bitextract_32(msb, lsb, value_);
+  }
+
+  int32_t SignedBits(int msb, int lsb) const {
+    return signed_bitextract_32(msb, lsb, value_);
+  }
+
+  void SetBits(int msb, int lsb, uint32_t bits);
+
+  // Default system register values.
+  static SimSystemRegister DefaultValueFor(SystemRegister id);
+
+#define DEFINE_GETTER(Name, HighBit, LowBit, Func, Type)                       \
+  Type Name() const { return static_cast<Type>(Func(HighBit, LowBit)); }       \
+  void Set##Name(Type bits) {                                                  \
+    SetBits(HighBit, LowBit, static_cast<Type>(bits));                         \
+  }
+#define DEFINE_WRITE_IGNORE_MASK(Name, Mask)                                   \
+  static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
+  SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
+#undef DEFINE_ZERO_BITS
+#undef DEFINE_GETTER
+
+ protected:
+  // Most system registers only implement a few of the bits in the word. Other
+  // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
+  // describes the bits which are not modifiable.
+  SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
+      : value_(value), write_ignore_mask_(write_ignore_mask) { }
+
+  uint32_t value_;
+  uint32_t write_ignore_mask_;
+};
+
+
+// Represent a register (r0-r31, v0-v31).
+class SimRegisterBase {
+ public:
+  template<typename T>
+  void Set(T new_value) {
+    value_ = 0;
+    memcpy(&value_, &new_value, sizeof(T));
+  }
+
+  template<typename T>
+  T Get() const {
+    T result;
+    memcpy(&result, &value_, sizeof(T));
+    return result;
+  }
+
+ protected:
+  int64_t value_;
+};
+
+
+typedef SimRegisterBase SimRegister;      // r0-r31
+typedef SimRegisterBase SimFPRegister;    // v0-v31
+
+
+class Simulator : public DecoderVisitor {
+ public:
+  explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
+                     Isolate* isolate = NULL,
+                     FILE* stream = stderr);
+  Simulator();
+  ~Simulator();
+
+  // System functions.
+
+  static void Initialize(Isolate* isolate);
+
+  static Simulator* current(v8::internal::Isolate* isolate);
+
+  class CallArgument;
+
+  // Call an arbitrary function taking an arbitrary number of arguments. The
+  // varargs list must be a set of arguments with type CallArgument, and
+  // terminated by CallArgument::End().
+  void CallVoid(byte* entry, CallArgument* args);
+
+  // Like CallVoid, but expect a return value.
+  int64_t CallInt64(byte* entry, CallArgument* args);
+  double CallDouble(byte* entry, CallArgument* args);
+
+  // V8 calls into generated JS code with 5 parameters and into
+  // generated RegExp code with 10 parameters. These are convenience functions,
+  // which set up the simulator state and grab the result on return.
+  int64_t CallJS(byte* entry,
+                 byte* function_entry,
+                 JSFunction* func,
+                 Object* revc,
+                 int64_t argc,
+                 Object*** argv);
+  int64_t CallRegExp(byte* entry,
+                     String* input,
+                     int64_t start_offset,
+                     const byte* input_start,
+                     const byte* input_end,
+                     int* output,
+                     int64_t output_size,
+                     Address stack_base,
+                     int64_t direct_call,
+                     void* return_address,
+                     Isolate* isolate);
+
+  // A wrapper class that stores an argument for one of the above Call
+  // functions.
+  //
+  // Only arguments up to 64 bits in size are supported.
+  class CallArgument {
+   public:
+    template<typename T>
+    explicit CallArgument(T argument) {
+      bits_ = 0;
+      DCHECK(sizeof(argument) <= sizeof(bits_));
+      memcpy(&bits_, &argument, sizeof(argument));
+      type_ = X_ARG;
+    }
+
+    explicit CallArgument(double argument) {
+      DCHECK(sizeof(argument) == sizeof(bits_));
+      memcpy(&bits_, &argument, sizeof(argument));
+      type_ = D_ARG;
+    }
+
+    explicit CallArgument(float argument) {
+      // TODO(all): CallArgument(float) is untested, remove this check once
+      //            tested.
+      UNIMPLEMENTED();
+      // Make the D register a NaN to try to trap errors if the callee expects a
+      // double. If it expects a float, the callee should ignore the top word.
+      DCHECK(sizeof(kFP64SignallingNaN) == sizeof(bits_));
+      memcpy(&bits_, &kFP64SignallingNaN, sizeof(kFP64SignallingNaN));
+      // Write the float payload to the S register.
+      DCHECK(sizeof(argument) <= sizeof(bits_));
+      memcpy(&bits_, &argument, sizeof(argument));
+      type_ = D_ARG;
+    }
+
+    // This indicates the end of the arguments list, so that CallArgument
+    // objects can be passed into varargs functions.
+    static CallArgument End() { return CallArgument(); }
+
+    int64_t bits() const { return bits_; }
+    bool IsEnd() const { return type_ == NO_ARG; }
+    bool IsX() const { return type_ == X_ARG; }
+    bool IsD() const { return type_ == D_ARG; }
+
+   private:
+    enum CallArgumentType { X_ARG, D_ARG, NO_ARG };
+
+    // All arguments are aligned to at least 64 bits and we don't support
+    // passing bigger arguments, so the payload size can be fixed at 64 bits.
+    int64_t bits_;
+    CallArgumentType type_;
+
+    CallArgument() { type_ = NO_ARG; }
+  };
+
+
+  // Start the debugging command line.
+  void Debug();
+
+  bool GetValue(const char* desc, int64_t* value);
+
+  bool PrintValue(const char* desc);
+
+  // Push an address onto the JS stack.
+  uintptr_t PushAddress(uintptr_t address);
+
+  // Pop an address from the JS stack.
+  uintptr_t PopAddress();
+
+  // Accessor to the internal simulator stack area.
+  uintptr_t StackLimit() const;
+
+  void ResetState();
+
+  // Runtime call support.
+  static void* RedirectExternalReference(void* external_function,
+                                         ExternalReference::Type type);
+  void DoRuntimeCall(Instruction* instr);
+
+  // Run the simulator.
+  static const Instruction* kEndOfSimAddress;
+  void DecodeInstruction();
+  void Run();
+  void RunFrom(Instruction* start);
+
+  // Simulation helpers.
+  template <typename T>
+  void set_pc(T new_pc) {
+    DCHECK(sizeof(T) == sizeof(pc_));
+    memcpy(&pc_, &new_pc, sizeof(T));
+    pc_modified_ = true;
+  }
+  Instruction* pc() { return pc_; }
+
+  void increment_pc() {
+    if (!pc_modified_) {
+      pc_ = pc_->following();
+    }
+
+    pc_modified_ = false;
+  }
+
+  virtual void Decode(Instruction* instr) {
+    decoder_->Decode(instr);
+  }
+
+  void ExecuteInstruction() {
+    DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize));
+    CheckBreakNext();
+    Decode(pc_);
+    increment_pc();
+    CheckBreakpoints();
+  }
+
+  // Declare all Visitor functions.
+  #define DECLARE(A)  void Visit##A(Instruction* instr);
+  VISITOR_LIST(DECLARE)
+  #undef DECLARE
+
+  bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const {
+    return ((code == 31) && (r31mode == Reg31IsZeroRegister));
+  }
+
+  // Register accessors.
+  // Return 'size' bits of the value of an integer register, as the specified
+  // type. The value is zero-extended to fill the result.
+  //
+  template<typename T>
+  T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
+    DCHECK(code < kNumberOfRegisters);
+    if (IsZeroRegister(code, r31mode)) {
+      return 0;
+    }
+    return registers_[code].Get<T>();
+  }
+
+  // Common specialized accessors for the reg() template.
+  int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
+    return reg<int32_t>(code, r31mode);
+  }
+
+  int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
+    return reg<int64_t>(code, r31mode);
+  }
+
+  // Write 'value' into an integer register. The value is zero-extended. This
+  // behaviour matches AArch64 register writes.
+  template<typename T>
+  void set_reg(unsigned code, T value,
+               Reg31Mode r31mode = Reg31IsZeroRegister) {
+    set_reg_no_log(code, value, r31mode);
+    LogRegister(code, r31mode);
+  }
+
+  // Common specialized accessors for the set_reg() template.
+  void set_wreg(unsigned code, int32_t value,
+                Reg31Mode r31mode = Reg31IsZeroRegister) {
+    set_reg(code, value, r31mode);
+  }
+
+  void set_xreg(unsigned code, int64_t value,
+                Reg31Mode r31mode = Reg31IsZeroRegister) {
+    set_reg(code, value, r31mode);
+  }
+
+  // As above, but don't automatically log the register update.
+  template <typename T>
+  void set_reg_no_log(unsigned code, T value,
+                      Reg31Mode r31mode = Reg31IsZeroRegister) {
+    DCHECK(code < kNumberOfRegisters);
+    if (!IsZeroRegister(code, r31mode)) {
+      registers_[code].Set(value);
+    }
+  }
+
+  void set_wreg_no_log(unsigned code, int32_t value,
+                       Reg31Mode r31mode = Reg31IsZeroRegister) {
+    set_reg_no_log(code, value, r31mode);
+  }
+
+  void set_xreg_no_log(unsigned code, int64_t value,
+                       Reg31Mode r31mode = Reg31IsZeroRegister) {
+    set_reg_no_log(code, value, r31mode);
+  }
+
+  // Commonly-used special cases.
+  template<typename T>
+  void set_lr(T value) {
+    DCHECK(sizeof(T) == kPointerSize);
+    set_reg(kLinkRegCode, value);
+  }
+
+  template<typename T>
+  void set_sp(T value) {
+    DCHECK(sizeof(T) == kPointerSize);
+    set_reg(31, value, Reg31IsStackPointer);
+  }
+
+  int64_t sp() { return xreg(31, Reg31IsStackPointer); }
+  int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); }
+  int64_t fp() {
+      return xreg(kFramePointerRegCode, Reg31IsStackPointer);
+  }
+  Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
+
+  Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); }
+
+  template<typename T>
+  T fpreg(unsigned code) const {
+    DCHECK(code < kNumberOfRegisters);
+    return fpregisters_[code].Get<T>();
+  }
+
+  // Common specialized accessors for the fpreg() template.
+  float sreg(unsigned code) const {
+    return fpreg<float>(code);
+  }
+
+  uint32_t sreg_bits(unsigned code) const {
+    return fpreg<uint32_t>(code);
+  }
+
+  double dreg(unsigned code) const {
+    return fpreg<double>(code);
+  }
+
+  uint64_t dreg_bits(unsigned code) const {
+    return fpreg<uint64_t>(code);
+  }
+
+  double fpreg(unsigned size, unsigned code) const {
+    switch (size) {
+      case kSRegSizeInBits: return sreg(code);
+      case kDRegSizeInBits: return dreg(code);
+      default:
+        UNREACHABLE();
+        return 0.0;
+    }
+  }
+
+  // Write 'value' into a floating-point register. The value is zero-extended.
+  // This behaviour matches AArch64 register writes.
+  template<typename T>
+  void set_fpreg(unsigned code, T value) {
+    set_fpreg_no_log(code, value);
+
+    if (sizeof(value) <= kSRegSize) {
+      LogFPRegister(code, kPrintSRegValue);
+    } else {
+      LogFPRegister(code, kPrintDRegValue);
+    }
+  }
+
+  // Common specialized accessors for the set_fpreg() template.
+  void set_sreg(unsigned code, float value) {
+    set_fpreg(code, value);
+  }
+
+  void set_sreg_bits(unsigned code, uint32_t value) {
+    set_fpreg(code, value);
+  }
+
+  void set_dreg(unsigned code, double value) {
+    set_fpreg(code, value);
+  }
+
+  void set_dreg_bits(unsigned code, uint64_t value) {
+    set_fpreg(code, value);
+  }
+
+  // As above, but don't automatically log the register update.
+  template <typename T>
+  void set_fpreg_no_log(unsigned code, T value) {
+    DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize));
+    DCHECK(code < kNumberOfFPRegisters);
+    fpregisters_[code].Set(value);
+  }
+
+  void set_sreg_no_log(unsigned code, float value) {
+    set_fpreg_no_log(code, value);
+  }
+
+  void set_dreg_no_log(unsigned code, double value) {
+    set_fpreg_no_log(code, value);
+  }
+
+  SimSystemRegister& nzcv() { return nzcv_; }
+  SimSystemRegister& fpcr() { return fpcr_; }
+
+  // Debug helpers
+
+  // Simulator breakpoints.
+  struct Breakpoint {
+    Instruction* location;
+    bool enabled;
+  };
+  std::vector<Breakpoint> breakpoints_;
+  void SetBreakpoint(Instruction* breakpoint);
+  void ListBreakpoints();
+  void CheckBreakpoints();
+
+  // Helpers for the 'next' command.
+  // When this is set, the Simulator will insert a breakpoint after the next BL
+  // instruction it meets.
+  bool break_on_next_;
+  // Check if the Simulator should insert a break after the current instruction
+  // for the 'next' command.
+  void CheckBreakNext();
+
+  // Disassemble instruction at the given address.
+  void PrintInstructionsAt(Instruction* pc, uint64_t count);
+
+  // Print all registers of the specified types.
+  void PrintRegisters();
+  void PrintFPRegisters();
+  void PrintSystemRegisters();
+
+  // Like Print* (above), but respect log_parameters().
+  void LogSystemRegisters() {
+    if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters();
+  }
+  void LogRegisters() {
+    if (log_parameters() & LOG_REGS) PrintRegisters();
+  }
+  void LogFPRegisters() {
+    if (log_parameters() & LOG_FP_REGS) PrintFPRegisters();
+  }
+
+  // Specify relevant register sizes, for PrintFPRegister.
+  //
+  // These values are bit masks; they can be combined in case multiple views of
+  // a machine register are interesting.
+  enum PrintFPRegisterSizes {
+    kPrintDRegValue = 1 << kDRegSize,
+    kPrintSRegValue = 1 << kSRegSize,
+    kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue
+  };
+
+  // Print individual register values (after update).
+  void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
+  void PrintFPRegister(unsigned code,
+                       PrintFPRegisterSizes sizes = kPrintAllFPRegValues);
+  void PrintSystemRegister(SystemRegister id);
+
+  // Like Print* (above), but respect log_parameters().
+  void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
+    if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode);
+  }
+  void LogFPRegister(unsigned code,
+                     PrintFPRegisterSizes sizes = kPrintAllFPRegValues) {
+    if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes);
+  }
+  void LogSystemRegister(SystemRegister id) {
+    if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id);
+  }
+
+  // Print memory accesses.
+  void PrintRead(uintptr_t address, size_t size, unsigned reg_code);
+  void PrintReadFP(uintptr_t address, size_t size, unsigned reg_code);
+  void PrintWrite(uintptr_t address, size_t size, unsigned reg_code);
+  void PrintWriteFP(uintptr_t address, size_t size, unsigned reg_code);
+
+  // Like Print* (above), but respect log_parameters().
+  void LogRead(uintptr_t address, size_t size, unsigned reg_code) {
+    if (log_parameters() & LOG_REGS) PrintRead(address, size, reg_code);
+  }
+  void LogReadFP(uintptr_t address, size_t size, unsigned reg_code) {
+    if (log_parameters() & LOG_FP_REGS) PrintReadFP(address, size, reg_code);
+  }
+  void LogWrite(uintptr_t address, size_t size, unsigned reg_code) {
+    if (log_parameters() & LOG_WRITE) PrintWrite(address, size, reg_code);
+  }
+  void LogWriteFP(uintptr_t address, size_t size, unsigned reg_code) {
+    if (log_parameters() & LOG_WRITE) PrintWriteFP(address, size, reg_code);
+  }
+
+  int log_parameters() { return log_parameters_; }
+  void set_log_parameters(int new_parameters) {
+    log_parameters_ = new_parameters;
+    if (!decoder_) {
+      if (new_parameters & LOG_DISASM) {
+        PrintF("Run --debug-sim to dynamically turn on disassembler\n");
+      }
+      return;
+    }
+    if (new_parameters & LOG_DISASM) {
+      decoder_->InsertVisitorBefore(print_disasm_, this);
+    } else {
+      decoder_->RemoveVisitor(print_disasm_);
+    }
+  }
+
+  static inline const char* WRegNameForCode(unsigned code,
+      Reg31Mode mode = Reg31IsZeroRegister);
+  static inline const char* XRegNameForCode(unsigned code,
+      Reg31Mode mode = Reg31IsZeroRegister);
+  static inline const char* SRegNameForCode(unsigned code);
+  static inline const char* DRegNameForCode(unsigned code);
+  static inline const char* VRegNameForCode(unsigned code);
+  static inline int CodeFromName(const char* name);
+
+ protected:
+  // Simulation helpers ------------------------------------
+  bool ConditionPassed(Condition cond) {
+    SimSystemRegister& flags = nzcv();
+    switch (cond) {
+      case eq:
+        return flags.Z();
+      case ne:
+        return !flags.Z();
+      case hs:
+        return flags.C();
+      case lo:
+        return !flags.C();
+      case mi:
+        return flags.N();
+      case pl:
+        return !flags.N();
+      case vs:
+        return flags.V();
+      case vc:
+        return !flags.V();
+      case hi:
+        return flags.C() && !flags.Z();
+      case ls:
+        return !(flags.C() && !flags.Z());
+      case ge:
+        return flags.N() == flags.V();
+      case lt:
+        return flags.N() != flags.V();
+      case gt:
+        return !flags.Z() && (flags.N() == flags.V());
+      case le:
+        return !(!flags.Z() && (flags.N() == flags.V()));
+      case nv:  // Fall through.
+      case al:
+        return true;
+      default:
+        UNREACHABLE();
+        return false;
+    }
+  }
+
+  bool ConditionFailed(Condition cond) {
+    return !ConditionPassed(cond);
+  }
+
+  template<typename T>
+  void AddSubHelper(Instruction* instr, T op2);
+  template<typename T>
+  T AddWithCarry(bool set_flags,
+                 T src1,
+                 T src2,
+                 T carry_in = 0);
+  template<typename T>
+  void AddSubWithCarry(Instruction* instr);
+  template<typename T>
+  void LogicalHelper(Instruction* instr, T op2);
+  template<typename T>
+  void ConditionalCompareHelper(Instruction* instr, T op2);
+  void LoadStoreHelper(Instruction* instr,
+                       int64_t offset,
+                       AddrMode addrmode);
+  void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
+  uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset,
+                             AddrMode addrmode);
+  void LoadStoreWriteBack(unsigned addr_reg,
+                          int64_t offset,
+                          AddrMode addrmode);
+  void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
+
+  // Memory read helpers.
+  template <typename T, typename A>
+  T MemoryRead(A address) {
+    T value;
+    STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
+                  (sizeof(value) == 4) || (sizeof(value) == 8));
+    memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value));
+    return value;
+  }
+
+  // Memory write helpers.
+  template <typename T, typename A>
+  void MemoryWrite(A address, T value) {
+    STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
+                  (sizeof(value) == 4) || (sizeof(value) == 8));
+    memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
+  }
+
+  template <typename T>
+  T ShiftOperand(T value,
+                 Shift shift_type,
+                 unsigned amount);
+  template <typename T>
+  T ExtendValue(T value,
+                Extend extend_type,
+                unsigned left_shift = 0);
+  template <typename T>
+  void Extract(Instruction* instr);
+  template <typename T>
+  void DataProcessing2Source(Instruction* instr);
+  template <typename T>
+  void BitfieldHelper(Instruction* instr);
+
+  uint64_t ReverseBits(uint64_t value, unsigned num_bits);
+  uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode);
+
+  template <typename T>
+  T FPDefaultNaN() const;
+
+  void FPCompare(double val0, double val1);
+  double FPRoundInt(double value, FPRounding round_mode);
+  double FPToDouble(float value);
+  float FPToFloat(double value, FPRounding round_mode);
+  double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
+  double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
+  float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
+  float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
+  int32_t FPToInt32(double value, FPRounding rmode);
+  int64_t FPToInt64(double value, FPRounding rmode);
+  uint32_t FPToUInt32(double value, FPRounding rmode);
+  uint64_t FPToUInt64(double value, FPRounding rmode);
+
+  template <typename T>
+  T FPAdd(T op1, T op2);
+
+  template <typename T>
+  T FPDiv(T op1, T op2);
+
+  template <typename T>
+  T FPMax(T a, T b);
+
+  template <typename T>
+  T FPMaxNM(T a, T b);
+
+  template <typename T>
+  T FPMin(T a, T b);
+
+  template <typename T>
+  T FPMinNM(T a, T b);
+
+  template <typename T>
+  T FPMul(T op1, T op2);
+
+  template <typename T>
+  T FPMulAdd(T a, T op1, T op2);
+
+  template <typename T>
+  T FPSqrt(T op);
+
+  template <typename T>
+  T FPSub(T op1, T op2);
+
+  // Standard NaN processing.
+  template <typename T>
+  T FPProcessNaN(T op);
+
+  bool FPProcessNaNs(Instruction* instr);
+
+  template <typename T>
+  T FPProcessNaNs(T op1, T op2);
+
+  template <typename T>
+  T FPProcessNaNs3(T op1, T op2, T op3);
+
+  void CheckStackAlignment();
+
+  inline void CheckPCSComplianceAndRun();
+
+#ifdef DEBUG
+  // Corruption values should have their least significant byte cleared to
+  // allow the code of the register being corrupted to be inserted.
+  static const uint64_t kCallerSavedRegisterCorruptionValue =
+      0xca11edc0de000000UL;
+  // This value is a NaN in both 32-bit and 64-bit FP.
+  static const uint64_t kCallerSavedFPRegisterCorruptionValue =
+      0x7ff000007f801000UL;
+  // This value is a mix of 32/64-bits NaN and "verbose" immediate.
+  static const uint64_t kDefaultCPURegisterCorruptionValue =
+      0x7ffbad007f8bad00UL;
+
+  void CorruptRegisters(CPURegList* list,
+                        uint64_t value = kDefaultCPURegisterCorruptionValue);
+  void CorruptAllCallerSavedCPURegisters();
+#endif
+
+  // Pseudo Printf instruction
+  void DoPrintf(Instruction* instr);
+
+  // Processor state ---------------------------------------
+
+  // Output stream.
+  FILE* stream_;
+  PrintDisassembler* print_disasm_;
+  void PRINTF_METHOD_CHECKING TraceSim(const char* format, ...);
+
+  // Instrumentation.
+  Instrument* instrument_;
+
+  // General purpose registers. Register 31 is the stack pointer.
+  SimRegister registers_[kNumberOfRegisters];
+
+  // Floating point registers
+  SimFPRegister fpregisters_[kNumberOfFPRegisters];
+
+  // Processor state
+  // bits[31, 27]: Condition flags N, Z, C, and V.
+  //               (Negative, Zero, Carry, Overflow)
+  SimSystemRegister nzcv_;
+
+  // Floating-Point Control Register
+  SimSystemRegister fpcr_;
+
+  // Only a subset of FPCR features are supported by the simulator. This helper
+  // checks that the FPCR settings are supported.
+  //
+  // This is checked when floating-point instructions are executed, not when
+  // FPCR is set. This allows generated code to modify FPCR for external
+  // functions, or to save and restore it when entering and leaving generated
+  // code.
+  void AssertSupportedFPCR() {
+    DCHECK(fpcr().FZ() == 0);             // No flush-to-zero support.
+    DCHECK(fpcr().RMode() == FPTieEven);  // Ties-to-even rounding only.
+
+    // The simulator does not support half-precision operations so fpcr().AHP()
+    // is irrelevant, and is not checked here.
+  }
+
+  template <typename T>
+  static int CalcNFlag(T result) {
+    return (result >> (sizeof(T) * 8 - 1)) & 1;
+  }
+
+  static int CalcZFlag(uint64_t result) {
+    return result == 0;
+  }
+
+  static const uint32_t kConditionFlagsMask = 0xf0000000;
+
+  // Stack
+  uintptr_t stack_;
+  static const size_t stack_protection_size_ = KB;
+  size_t stack_size_;
+  uintptr_t stack_limit_;
+
+  Decoder<DispatchingDecoderVisitor>* decoder_;
+  Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
+
+  // Indicates if the pc has been modified by the instruction and should not be
+  // automatically incremented.
+  bool pc_modified_;
+  Instruction* pc_;
+
+  static const char* xreg_names[];
+  static const char* wreg_names[];
+  static const char* sreg_names[];
+  static const char* dreg_names[];
+  static const char* vreg_names[];
+
+  // Debugger input.
+  void set_last_debugger_input(char* input) {
+    DeleteArray(last_debugger_input_);
+    last_debugger_input_ = input;
+  }
+  char* last_debugger_input() { return last_debugger_input_; }
+  char* last_debugger_input_;
+
+ private:
+  void Init(FILE* stream);
+
+  int  log_parameters_;
+  Isolate* isolate_;
+};
+
+
+// When running with the simulator transition into simulated execution at this
+// point.
+#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
+  reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->CallJS(    \
+      FUNCTION_ADDR(entry),                                                    \
+      p0, p1, p2, p3, p4))
+
+#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8)  \
+  Simulator::current(Isolate::Current())->CallRegExp(                          \
+      entry,                                                                   \
+      p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8)
+
+
+// The simulator has its own stack. Thus it has a different stack limit from
+// the C-based native code.
+// See also 'class SimulatorStack' in arm/simulator-arm.h.
+class SimulatorStack : public v8::internal::AllStatic {
+ public:
+  static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
+                                            uintptr_t c_limit) {
+    return Simulator::current(isolate)->StackLimit();
+  }
+
+  static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
+    Simulator* sim = Simulator::current(Isolate::Current());
+    return sim->PushAddress(try_catch_address);
+  }
+
+  static void UnregisterCTryCatch() {
+    Simulator::current(Isolate::Current())->PopAddress();
+  }
+};
+
+#endif  // !defined(USE_SIMULATOR)
+
+} }  // namespace v8::internal
+
+#endif  // V8_ARM64_SIMULATOR_ARM64_H_
