// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <math.h>  // for isnan.
#include <setjmp.h>
#include <stdlib.h>

#include "vm/globals.h"
#if defined(TARGET_ARCH_ARM)

// Only build the simulator if not compiling for real ARM hardware.
#if !defined(HOST_ARCH_ARM)

#include "vm/simulator.h"

#include "vm/assembler.h"
#include "vm/constants_arm.h"
#include "vm/disassembler.h"
#include "vm/native_arguments.h"
#include "vm/thread.h"

namespace dart {

DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution.");
DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at.");


// This macro provides a platform independent use of sscanf. The reason for
// SScanF not being implemented in a platform independent way through
// OS in the same way as SNPrint is that the Windows C Run-Time
// Library does not provide vsscanf.
#define SScanF sscanf  // NOLINT


// Unimplemented counter class for debugging and measurement purposes.
class StatsCounter {
 public:
  explicit StatsCounter(const char* name) {
    // UNIMPLEMENTED();
  }

  void Increment() {
    // UNIMPLEMENTED();
  }
};


// SimulatorSetjmpBuffer are linked together, and the last created one
// is referenced by the Simulator. When an exception is thrown, the exception
// runtime looks at where to jump and finds the corresponding
// SimulatorSetjmpBuffer based on the stack pointer of the exception handler.
// The runtime then does a Longjmp on that buffer to return to the simulator.
class SimulatorSetjmpBuffer {
 public:
  int Setjmp() { return setjmp(buffer_); }
  void Longjmp() {
    // "This" is now the last setjmp buffer.
    simulator_->set_last_setjmp_buffer(this);
    longjmp(buffer_, 1);
  }

  explicit SimulatorSetjmpBuffer(Simulator* sim) {
    simulator_ = sim;
    link_ = sim->last_setjmp_buffer();
    sim->set_last_setjmp_buffer(this);
    sp_ = sim->get_register(SP);
  }

  ~SimulatorSetjmpBuffer() {
    ASSERT(simulator_->last_setjmp_buffer() == this);
    simulator_->set_last_setjmp_buffer(link_);
  }

  SimulatorSetjmpBuffer* link() { return link_; }

  int32_t sp() { return sp_; }

 private:
  int32_t sp_;
  Simulator* simulator_;
  SimulatorSetjmpBuffer* link_;
  jmp_buf buffer_;

  friend class Simulator;
};


// The SimulatorDebugger class is used by the simulator while debugging
// simulated ARM code.
class SimulatorDebugger {
 public:
  explicit SimulatorDebugger(Simulator* sim);
  ~SimulatorDebugger();

  void Stop(Instr* instr, const char* message);
  void Debug();
  char* ReadLine(const char* prompt);

 private:
  static const int32_t kSimulatorBreakpointInstr =  // svc #kBreakpointSvcCode
    ((AL << kConditionShift) | (0xf << 24) | kBreakpointSvcCode);
  static const int32_t kNopInstr =  // nop
    ((AL << kConditionShift) | (0x32 << 20) | (0xf << 12));

  Simulator* sim_;

  bool GetValue(char* desc, uint32_t* value);
  bool GetFValue(char* desc, float* value);
  bool GetDValue(char* desc, double* value);

  // Set or delete a breakpoint. Returns true if successful.
  bool SetBreakpoint(Instr* breakpc);
  bool DeleteBreakpoint(Instr* breakpc);

  // Undo and redo all breakpoints. This is needed to bracket disassembly and
  // execution to skip past breakpoints when run from the debugger.
  void UndoBreakpoints();
  void RedoBreakpoints();
};


SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
  sim_ = sim;
}


SimulatorDebugger::~SimulatorDebugger() {
}


void SimulatorDebugger::Stop(Instr* instr, const char* message) {
  OS::Print("Simulator hit %s\n", message);
  Debug();
}


static Register LookupCoreRegisterByName(const char* name) {
  static const char* kNames[] = {
      "r0",  "r1",  "r2",  "r3",
      "r4",  "r5",  "r6",  "r7",
      "r8",  "r9",  "r10", "r11",
      "r12", "r13", "r14", "r15",
      "pc",  "lr",  "sp",  "ip",
      "fp",  "sl"
  };
  static const Register kRegisters[] = {
      R0,  R1,  R2,  R3,
      R4,  R5,  R6,  R7,
      R8,  R9,  R10, R11,
      R12, R13, R14, R15,
      PC,  LR,  SP,  IP,
      FP,  R10
  };
  ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
  for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
    if (strcmp(kNames[i], name) == 0) {
      return kRegisters[i];
    }
  }
  return kNoRegister;
}


static SRegister LookupSRegisterByName(const char* name) {
  int reg_nr = -1;
  bool ok = SScanF(name, "s%d", &reg_nr);
  if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfSRegisters)) {
    return static_cast<SRegister>(reg_nr);
  }
  return kNoSRegister;
}


static DRegister LookupDRegisterByName(const char* name) {
  int reg_nr = -1;
  bool ok = SScanF(name, "d%d", &reg_nr);
  if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfDRegisters)) {
    return static_cast<DRegister>(reg_nr);
  }
  return kNoDRegister;
}


bool SimulatorDebugger::GetValue(char* desc, uint32_t* value) {
  Register reg = LookupCoreRegisterByName(desc);
  if (reg != kNoRegister) {
    if (reg == PC) {
      *value = sim_->get_pc();
    } else {
      *value = sim_->get_register(reg);
    }
    return true;
  }
  if ((desc[0] == '*')) {
    uint32_t addr;
    if (GetValue(desc + 1, &addr)) {
      *value = *(reinterpret_cast<uint32_t*>(addr));
      return true;
    }
  }
  bool retval = SScanF(desc, "0x%x", value) == 1;
  if (!retval) {
    retval = SScanF(desc, "%x", value) == 1;
  }
  return retval;
}


bool SimulatorDebugger::GetFValue(char* desc, float* value) {
  SRegister sreg = LookupSRegisterByName(desc);
  if (sreg != kNoSRegister) {
    *value = sim_->get_sregister(sreg);
    return true;
  }
  if ((desc[0] == '*')) {
    uint32_t addr;
    if (GetValue(desc + 1, &addr)) {
      *value = *(reinterpret_cast<float*>(addr));
      return true;
    }
  }
  return false;
}


bool SimulatorDebugger::GetDValue(char* desc, double* value) {
  DRegister dreg = LookupDRegisterByName(desc);
  if (dreg != kNoDRegister) {
    *value = sim_->get_dregister(dreg);
    return true;
  }
  if ((desc[0] == '*')) {
    uint32_t addr;
    if (GetValue(desc + 1, &addr)) {
      *value = *(reinterpret_cast<double*>(addr));
      return true;
    }
  }
  return false;
}


bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
  // Check if a breakpoint can be set. If not return without any side-effects.
  if (sim_->break_pc_ != NULL) {
    return false;
  }

  // Set the breakpoint.
  sim_->break_pc_ = breakpc;
  sim_->break_instr_ = breakpc->InstructionBits();
  // Not setting the breakpoint instruction in the code itself. It will be set
  // when the debugger shell continues.
  return true;
}


bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) {
  if (sim_->break_pc_ != NULL) {
    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
  }

  sim_->break_pc_ = NULL;
  sim_->break_instr_ = 0;
  return true;
}


void SimulatorDebugger::UndoBreakpoints() {
  if (sim_->break_pc_ != NULL) {
    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
  }
}


void SimulatorDebugger::RedoBreakpoints() {
  if (sim_->break_pc_ != NULL) {
    sim_->break_pc_->SetInstructionBits(kSimulatorBreakpointInstr);
  }
}


void SimulatorDebugger::Debug() {
  intptr_t last_pc = -1;
  bool done = false;

#define COMMAND_SIZE 63
#define ARG_SIZE 255

#define STR(a) #a
#define XSTR(a) STR(a)

  char cmd[COMMAND_SIZE + 1];
  char arg1[ARG_SIZE + 1];
  char arg2[ARG_SIZE + 1];

  // make sure to have a proper terminating character if reaching the limit
  cmd[COMMAND_SIZE] = 0;
  arg1[ARG_SIZE] = 0;
  arg2[ARG_SIZE] = 0;

  // Undo all set breakpoints while running in the debugger shell. This will
  // make them invisible to all commands.
  UndoBreakpoints();

  while (!done) {
    if (last_pc != sim_->get_pc()) {
      last_pc = sim_->get_pc();
      Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
    }
    char* line = ReadLine("sim> ");
    if (line == NULL) {
      break;
    } else {
      // Use sscanf to parse the individual parts of the command line. At the
      // moment no command expects more than two parameters.
      int args = SScanF(line,
                        "%" XSTR(COMMAND_SIZE) "s "
                        "%" XSTR(ARG_SIZE) "s "
                        "%" XSTR(ARG_SIZE) "s",
                        cmd, arg1, arg2);
      if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
        OS::Print("c/cont -- continue execution\n"
                  "disasm -- disassemble instrs at current pc location\n"
                  "  other variants are:\n"
                  "    disasm <address>\n"
                  "    disasm <address> <number_of_instructions>\n"
                  "  by default 10 instrs are disassembled\n"
                  "del -- delete breakpoints\n"
                  "flags -- print flag values\n"
                  "gdb -- transfer control to gdb\n"
                  "h/help -- print this help string\n"
                  "break <address> -- set break point at specified address\n"
                  "p/print <reg or value or *addr> -- print integer value\n"
                  "pf/printfloat <sreg or *addr> -- print float value\n"
                  "pd/printdouble <dreg or *addr> -- print double value\n"
                  "po/printobject <*reg or *addr> -- print object\n"
                  "si/stepi -- single step an instruction\n"
                  "unstop -- if current pc is a stop instr make it a nop\n");
      } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
        sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
      } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
        // Execute the one instruction we broke at with breakpoints disabled.
        sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
        // Leave the debugger shell.
        done = true;
      } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
        if (args == 2) {
          uint32_t value;
          if (GetValue(arg1, &value)) {
            OS::Print("%s: %u 0x%x\n", arg1, value, value);
          } else {
            OS::Print("%s unrecognized\n", arg1);
          }
        } else {
          OS::Print("print <reg or value or *addr>\n");
        }
      } else if ((strcmp(cmd, "pf") == 0) || (strcmp(cmd, "printfloat") == 0)) {
        if (args == 2) {
          float fvalue;
          if (GetFValue(arg1, &fvalue)) {
            uint32_t value = bit_cast<uint32_t, float>(fvalue);
            OS::Print("%s: 0%u 0x%x %.8g\n", arg1, value, value, fvalue);
          } else {
            OS::Print("%s unrecognized\n", arg1);
          }
        } else {
          OS::Print("printfloat <sreg or *addr>\n");
        }
      } else if ((strcmp(cmd, "pd") == 0) ||
                 (strcmp(cmd, "printdouble") == 0)) {
        if (args == 2) {
          double dvalue;
          if (GetDValue(arg1, &dvalue)) {
            uint64_t long_value = bit_cast<uint64_t, double>(dvalue);
            OS::Print("%s: %llu 0x%llx %.8g\n",
                arg1, long_value, long_value, dvalue);
          } else {
            OS::Print("%s unrecognized\n", arg1);
          }
        } else {
          OS::Print("printdouble <dreg or *addr>\n");
        }
      } else if ((strcmp(cmd, "po") == 0) ||
                 (strcmp(cmd, "printobject") == 0)) {
        if (args == 2) {
          uint32_t value;
          // Make the dereferencing '*' optional.
          if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
              GetValue(arg1, &value)) {
            if (Isolate::Current()->heap()->Contains(value)) {
              OS::Print("%s: \n", arg1);
#if defined(DEBUG)
              const Object& obj = Object::Handle(
                  reinterpret_cast<RawObject*>(value));
              obj.Print();
#endif  // defined(DEBUG)
            } else {
              OS::Print("0x%x is not an object reference\n", value);
            }
          } else {
            OS::Print("%s unrecognized\n", arg1);
          }
        } else {
          OS::Print("printobject <*reg or *addr>\n");
        }
      } else if (strcmp(cmd, "disasm") == 0) {
        uint32_t start = 0;
        uint32_t end = 0;
        if (args == 1) {
          start = sim_->get_pc();
          end = start + (10 * Instr::kInstrSize);
        } else if (args == 2) {
          if (GetValue(arg1, &start)) {
            // no length parameter passed, assume 10 instructions
            end = start + (10 * Instr::kInstrSize);
          }
        } else {
          uint32_t length;
          if (GetValue(arg1, &start) && GetValue(arg2, &length)) {
            end = start + (length * Instr::kInstrSize);
          }
        }

        Disassembler::Disassemble(start, end);
      } else if (strcmp(cmd, "gdb") == 0) {
        OS::Print("relinquishing control to gdb\n");
        OS::DebugBreak();
        OS::Print("regaining control from gdb\n");
      } else if (strcmp(cmd, "break") == 0) {
        if (args == 2) {
          uint32_t addr;
          if (GetValue(arg1, &addr)) {
            if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) {
              OS::Print("setting breakpoint failed\n");
            }
          } else {
            OS::Print("%s unrecognized\n", arg1);
          }
        } else {
          OS::Print("break <addr>\n");
        }
      } else if (strcmp(cmd, "del") == 0) {
        if (!DeleteBreakpoint(NULL)) {
          OS::Print("deleting breakpoint failed\n");
        }
      } else if (strcmp(cmd, "flags") == 0) {
        OS::Print("APSR: ");
        OS::Print("N flag: %d; ", sim_->n_flag_);
        OS::Print("Z flag: %d; ", sim_->z_flag_);
        OS::Print("C flag: %d; ", sim_->c_flag_);
        OS::Print("V flag: %d\n", sim_->v_flag_);
        OS::Print("FPSCR: ");
        OS::Print("N flag: %d; ", sim_->fp_n_flag_);
        OS::Print("Z flag: %d; ", sim_->fp_z_flag_);
        OS::Print("C flag: %d; ", sim_->fp_c_flag_);
        OS::Print("V flag: %d\n", sim_->fp_v_flag_);
      } else if (strcmp(cmd, "unstop") == 0) {
        intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
        Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
        if (stop_instr->IsSvc() || stop_instr->IsBkpt()) {
          stop_instr->SetInstructionBits(kNopInstr);
        } else {
          OS::Print("Not at debugger stop.\n");
        }
      } else {
        OS::Print("Unknown command: %s\n", cmd);
      }
    }
    delete[] line;
  }

  // Add all the breakpoints back to stop execution and enter the debugger
  // shell when hit.
  RedoBreakpoints();

#undef COMMAND_SIZE
#undef ARG_SIZE

#undef STR
#undef XSTR
}

char* SimulatorDebugger::ReadLine(const char* prompt) {
  char* result = NULL;
  char line_buf[256];
  int offset = 0;
  bool keep_going = true;
  fprintf(stdout, "%s", prompt);
  fflush(stdout);
  while (keep_going) {
    if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
      // fgets got an error. Just give up.
      if (result != NULL) {
        delete[] result;
      }
      return NULL;
    }
    int len = strlen(line_buf);
    if (len > 1 &&
        line_buf[len - 2] == '\\' &&
        line_buf[len - 1] == '\n') {
      // When we read a line that ends with a "\" we remove the escape and
      // append the remainder.
      line_buf[len - 2] = '\n';
      line_buf[len - 1] = 0;
      len -= 1;
    } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
      // Since we read a new line we are done reading the line. This
      // will exit the loop after copying this buffer into the result.
      keep_going = false;
    }
    if (result == NULL) {
      // Allocate the initial result and make room for the terminating '\0'
      result = new char[len + 1];
      if (result == NULL) {
        // OOM, so cannot readline anymore.
        return NULL;
      }
    } else {
      // Allocate a new result with enough room for the new addition.
      int new_len = offset + len + 1;
      char* new_result = new char[new_len];
      if (new_result == NULL) {
        // OOM, free the buffer allocated so far and return NULL.
        delete[] result;
        return NULL;
      } else {
        // Copy the existing input into the new array and set the new
        // array as the result.
        memmove(new_result, result, offset);
        delete[] result;
        result = new_result;
      }
    }
    // Copy the newly read line into the result.
    memmove(result + offset, line_buf, len);
    offset += len;
  }
  ASSERT(result != NULL);
  result[offset] = '\0';
  return result;
}


// Synchronization primitives support.
Mutex* Simulator::exclusive_access_lock_ = NULL;
Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags];
int Simulator::next_address_tag_;


void Simulator::SetExclusiveAccess(uword addr) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  int i = 0;
  while ((i < kNumAddressTags) &&
         (exclusive_access_state_[i].isolate != isolate)) {
    i++;
  }
  if (i == kNumAddressTags) {
    i = next_address_tag_;
    if (++next_address_tag_ == kNumAddressTags) next_address_tag_ = 0;
    exclusive_access_state_[i].isolate = isolate;
  }
  exclusive_access_state_[i].addr = addr;
}


bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  bool result = false;
  for (int i = 0; i < kNumAddressTags; i++) {
    if (exclusive_access_state_[i].isolate == isolate) {
      if (exclusive_access_state_[i].addr == addr) {
        result = true;
      }
      exclusive_access_state_[i].addr = NULL;
      continue;
    }
    if (exclusive_access_state_[i].addr == addr) {
      exclusive_access_state_[i].addr = NULL;
    }
  }
  return result;
}


void Simulator::InitOnce() {
  // Setup exclusive access state.
  exclusive_access_lock_ = new Mutex();
  for (int i = 0; i < kNumAddressTags; i++) {
    exclusive_access_state_[i].isolate = NULL;
    exclusive_access_state_[i].addr = NULL;
  }
  next_address_tag_ = 0;
}


Simulator::Simulator() {
  // Setup simulator support first. Some of this information is needed to
  // setup the architecture state.
  // We allocate the stack here, the size is computed as the sum of
  // the size specified by the user and the buffer space needed for
  // handling stack overflow exceptions. To be safe in potential
  // stack underflows we also add some underflow buffer space.
  stack_ = new char[(Isolate::GetSpecifiedStackSize() +
                     Isolate::kStackSizeBuffer +
                     kSimulatorStackUnderflowSize)];
  pc_modified_ = false;
  icount_ = 0;
  break_pc_ = NULL;
  break_instr_ = 0;
  last_setjmp_buffer_ = NULL;

  // Setup architecture state.
  // All registers are initialized to zero to start with.
  for (int i = 0; i < kNumberOfCpuRegisters; i++) {
    registers_[i] = 0;
  }
  n_flag_ = false;
  z_flag_ = false;
  c_flag_ = false;
  v_flag_ = false;

  // The sp is initialized to point to the bottom (high address) of the
  // allocated stack area.
  registers_[SP] = StackTop();
  // The lr and pc are initialized to a known bad value that will cause an
  // access violation if the simulator ever tries to execute it.
  registers_[PC] = kBadLR;
  registers_[LR] = kBadLR;

  // All double-precision registers are initialized to zero.
  for (int i = 0; i < kNumberOfDRegisters; i++) {
    dregisters_[i] = 0.0;
  }
  // Since VFP registers are overlapping, single-precision registers should
  // already be initialized.
  ASSERT(2*kNumberOfDRegisters >= kNumberOfSRegisters);
  for (int i = 0; i < kNumberOfSRegisters; i++) {
    ASSERT(sregisters_[i] == 0.0);
  }
  fp_n_flag_ = false;
  fp_z_flag_ = false;
  fp_c_flag_ = false;
  fp_v_flag_ = false;
}


Simulator::~Simulator() {
  delete[] stack_;
  Isolate* isolate = Isolate::Current();
  if (isolate != NULL) {
    isolate->set_simulator(NULL);
  }
}


// When the generated code calls an external reference we need to catch that in
// the simulator.  The external reference will be a function compiled for the
// host architecture.  We need to call that function instead of trying to
// execute it with the simulator.  We do that by redirecting the external
// reference to a svc (supervisor call) instruction that is handled by
// the simulator.  We write the original destination of the jump just at a known
// offset from the svc instruction so the simulator knows what to call.
class Redirection {
 public:
  uword address_of_svc_instruction() {
    return reinterpret_cast<uword>(&svc_instruction_);
  }

  void* external_function() const { return external_function_; }

  uint32_t argument_count() const { return argument_count_; }

  static Redirection* Get(void* external_function, uint32_t argument_count) {
    Redirection* current;
    for (current = list_; current != NULL; current = current->next_) {
      if (current->external_function_ == external_function) return current;
    }
    return new Redirection(external_function, argument_count);
  }

  static Redirection* FromSvcInstruction(Instr* svc_instruction) {
    char* addr_of_svc = reinterpret_cast<char*>(svc_instruction);
    char* addr_of_redirection =
        addr_of_svc - OFFSET_OF(Redirection, svc_instruction_);
    return reinterpret_cast<Redirection*>(addr_of_redirection);
  }

 private:
  static const int32_t kRedirectSvcInstruction =
    ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode);
  Redirection(void* external_function, uint32_t argument_count)
      : external_function_(external_function),
        argument_count_(argument_count),
        svc_instruction_(kRedirectSvcInstruction),
        next_(list_) {
    list_ = this;
  }

  void* external_function_;
  const uint32_t argument_count_;
  uint32_t svc_instruction_;
  Redirection* next_;
  static Redirection* list_;
};


Redirection* Redirection::list_ = NULL;


uword Simulator::RedirectExternalReference(void* function,
                                           uint32_t argument_count) {
  Redirection* redirection = Redirection::Get(function, argument_count);
  return redirection->address_of_svc_instruction();
}


// Get the active Simulator for the current isolate.
Simulator* Simulator::Current() {
  Simulator* simulator = Isolate::Current()->simulator();
  if (simulator == NULL) {
    simulator = new Simulator();
    Isolate::Current()->set_simulator(simulator);
  }
  return simulator;
}


// Sets the register in the architecture state. It will also deal with updating
// Simulator internal state for special registers such as PC.
void Simulator::set_register(Register reg, int32_t value) {
  ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
  if (reg == PC) {
    pc_modified_ = true;
  }
  registers_[reg] = value;
}


// Get the register from the architecture state. This function does handle
// the special case of accessing the PC register.
int32_t Simulator::get_register(Register reg) const {
  ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
  return registers_[reg] + ((reg == PC) ? Instr::kPCReadOffset : 0);
}


// Raw access to the PC register.
void Simulator::set_pc(int32_t value) {
  pc_modified_ = true;
  registers_[PC] = value;
}


// Raw access to the PC register without the special adjustment when reading.
int32_t Simulator::get_pc() const {
  return registers_[PC];
}


// Accessors for VFP register state.
void Simulator::set_sregister(SRegister reg, float value) {
  ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
  sregisters_[reg] = value;
}


float Simulator::get_sregister(SRegister reg) const {
  ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
  return sregisters_[reg];
}


void Simulator::set_dregister(DRegister reg, double value) {
  ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
  dregisters_[reg] = value;
}


double Simulator::get_dregister(DRegister reg) const {
  ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
  return dregisters_[reg];
}


void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
  uword fault_pc = get_pc();
  // The debugger will not be able to single step past this instruction, but
  // it will be possible to disassemble the code and inspect registers.
  char buffer[128];
  snprintf(buffer, sizeof(buffer),
           "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
           addr, fault_pc);
  SimulatorDebugger dbg(this);
  dbg.Stop(instr, buffer);
  // The debugger will return control in non-interactive mode.
  FATAL("Cannot continue execution after illegal memory access.");
}


// Processor versions prior to ARMv7 could not do unaligned reads and writes.
// On some ARM platforms an interrupt is caused.  On others it does a funky
// rotation thing.  However, from version v7, unaligned access is supported.
// Note that simulator runs have the runtime system running directly on the host
// system and only generated code is executed in the simulator.  Since the host
// is typically IA32 we will get the correct ARMv7-like behaviour on unaligned
// accesses, but we should actually not generate code accessing unaligned data,
// so we still want to know and abort if we encounter such code.
void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
  // The debugger will not be able to single step past this instruction, but
  // it will be possible to disassemble the code and inspect registers.
  char buffer[64];
  snprintf(buffer, sizeof(buffer),
           "unaligned %s at 0x%"Px", pc=%p\n", msg, addr, instr);
  SimulatorDebugger dbg(this);
  dbg.Stop(instr, buffer);
  // The debugger will return control in non-interactive mode.
  FATAL("Cannot continue execution after unaligned access.");
}


int Simulator::ReadW(uword addr, Instr* instr) {
  static StatsCounter counter_read_w("Simulated word reads");
  counter_read_w.Increment();
  if ((addr & 3) == 0) {
    intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
    return *ptr;
  }
  UnalignedAccess("read", addr, instr);
  return 0;
}


void Simulator::WriteW(uword addr, int value, Instr* instr) {
  static StatsCounter counter_write_w("Simulated word writes");
  counter_write_w.Increment();
  if ((addr & 3) == 0) {
    intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
    *ptr = value;
    return;
  }
  UnalignedAccess("write", addr, instr);
}


uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
  static StatsCounter counter_read_hu("Simulated unsigned halfword reads");
  counter_read_hu.Increment();
  if ((addr & 1) == 0) {
    uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
    return *ptr;
  }
  UnalignedAccess("unsigned halfword read", addr, instr);
  return 0;
}


int16_t Simulator::ReadH(uword addr, Instr* instr) {
  static StatsCounter counter_read_h("Simulated signed halfword reads");
  counter_read_h.Increment();
  if ((addr & 1) == 0) {
    int16_t* ptr = reinterpret_cast<int16_t*>(addr);
    return *ptr;
  }
  UnalignedAccess("signed halfword read", addr, instr);
  return 0;
}


void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
  static StatsCounter counter_write_h("Simulated halfword writes");
  counter_write_h.Increment();
  if ((addr & 1) == 0) {
    uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
    *ptr = value;
    return;
  }
  UnalignedAccess("halfword write", addr, instr);
}


uint8_t Simulator::ReadBU(uword addr) {
  static StatsCounter counter_read_bu("Simulated unsigned byte reads");
  counter_read_bu.Increment();
  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
  return *ptr;
}


int8_t Simulator::ReadB(uword addr) {
  static StatsCounter counter_read_b("Simulated signed byte reads");
  counter_read_b.Increment();
  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
  return *ptr;
}


void Simulator::WriteB(uword addr, uint8_t value) {
  static StatsCounter counter_write_b("Simulated byte writes");
  counter_write_b.Increment();
  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
  *ptr = value;
}


// Synchronization primitives support.
void Simulator::ClearExclusive() {
  // This lock is initialized in Simulator::InitOnce().
  MutexLocker ml(exclusive_access_lock_);
  // Set exclusive access to open state for this isolate.
  HasExclusiveAccessAndOpen(NULL);
}


int Simulator::ReadExclusiveW(uword addr, Instr* instr) {
  // This lock is initialized in Simulator::InitOnce().
  MutexLocker ml(exclusive_access_lock_);
  SetExclusiveAccess(addr);
  return ReadW(addr, instr);
}


int Simulator::WriteExclusiveW(uword addr, int value, Instr* instr) {
  // This lock is initialized in Simulator::InitOnce().
  MutexLocker ml(exclusive_access_lock_);
  bool write_allowed = HasExclusiveAccessAndOpen(addr);
  if (write_allowed) {
    WriteW(addr, value, instr);
    return 0;  // Success.
  }
  return 1;  // Failure.
}


uword Simulator::CompareExchange(uword* address,
                                 uword compare_value,
                                 uword new_value) {
  // This lock is initialized in Simulator::InitOnce().
  MutexLocker ml(exclusive_access_lock_);
  uword value = *address;
  if (value == compare_value) {
    *address = new_value;
    // Same effect on exclusive access state as a successful STREX.
    HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
  } else {
    // Same effect on exclusive access state as an LDREX.
    SetExclusiveAccess(reinterpret_cast<uword>(address));
  }
  return value;
}


// Returns the top of the stack area to enable checking for stack pointer
// validity.
uintptr_t Simulator::StackTop() const {
  // To be safe in potential stack underflows we leave some buffer above and
  // set the stack top.
  return reinterpret_cast<uintptr_t>(stack_) +
      (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
}


// Unsupported instructions use Format to print an error and stop execution.
void Simulator::Format(Instr* instr, const char* format) {
  OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n",
            instr,
            format);
  UNIMPLEMENTED();
}


// Checks if the current instruction should be executed based on its
// condition bits.
bool Simulator::ConditionallyExecute(Instr* instr) {
  switch (instr->ConditionField()) {
    case EQ: return z_flag_;
    case NE: return !z_flag_;
    case CS: return c_flag_;
    case CC: return !c_flag_;
    case MI: return n_flag_;
    case PL: return !n_flag_;
    case VS: return v_flag_;
    case VC: return !v_flag_;
    case HI: return c_flag_ && !z_flag_;
    case LS: return !c_flag_ || z_flag_;
    case GE: return n_flag_ == v_flag_;
    case LT: return n_flag_ != v_flag_;
    case GT: return !z_flag_ && (n_flag_ == v_flag_);
    case LE: return z_flag_ || (n_flag_ != v_flag_);
    case AL: return true;
    default: UNREACHABLE();
  }
  return false;
}


// Calculate and set the Negative and Zero flags.
void Simulator::SetNZFlags(int32_t val) {
  n_flag_ = (val < 0);
  z_flag_ = (val == 0);
}


// Set the Carry flag.
void Simulator::SetCFlag(bool val) {
  c_flag_ = val;
}


// Set the oVerflow flag.
void Simulator::SetVFlag(bool val) {
  v_flag_ = val;
}


// Calculate C flag value for additions.
bool Simulator::CarryFrom(int32_t left, int32_t right) {
  uint32_t uleft = static_cast<uint32_t>(left);
  uint32_t uright = static_cast<uint32_t>(right);
  uint32_t urest  = 0xffffffffU - uleft;

  return (uright > urest);
}


// Calculate C flag value for subtractions.
bool Simulator::BorrowFrom(int32_t left, int32_t right) {
  uint32_t uleft = static_cast<uint32_t>(left);
  uint32_t uright = static_cast<uint32_t>(right);

  return (uright > uleft);
}


// Calculate V flag value for additions and subtractions.
bool Simulator::OverflowFrom(int32_t alu_out,
                             int32_t left, int32_t right, bool addition) {
  bool overflow;
  if (addition) {
               // operands have the same sign
    overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
               // and operands and result have different sign
               && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
  } else {
               // operands have different signs
    overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
               // and first operand and result have different signs
               && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
  }
  return overflow;
}


// Addressing Mode 1 - Data-processing operands:
// Get the value based on the shifter_operand with register.
int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) {
  Shift shift = instr->ShiftField();
  int shift_amount = instr->ShiftAmountField();
  int32_t result = get_register(instr->RmField());
  if (instr->Bit(4) == 0) {
    // by immediate
    if ((shift == ROR) && (shift_amount == 0)) {
      UNIMPLEMENTED();
      return result;
    } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
      shift_amount = 32;
    }
    switch (shift) {
      case ASR: {
        if (shift_amount == 0) {
          if (result < 0) {
            result = 0xffffffff;
            *carry_out = true;
          } else {
            result = 0;
            *carry_out = false;
          }
        } else {
          result >>= (shift_amount - 1);
          *carry_out = (result & 1) == 1;
          result >>= 1;
        }
        break;
      }

      case LSL: {
        if (shift_amount == 0) {
          *carry_out = c_flag_;
        } else {
          result <<= (shift_amount - 1);
          *carry_out = (result < 0);
          result <<= 1;
        }
        break;
      }

      case LSR: {
        if (shift_amount == 0) {
          result = 0;
          *carry_out = c_flag_;
        } else {
          uint32_t uresult = static_cast<uint32_t>(result);
          uresult >>= (shift_amount - 1);
          *carry_out = (uresult & 1) == 1;
          uresult >>= 1;
          result = static_cast<int32_t>(uresult);
        }
        break;
      }

      case ROR: {
        UNIMPLEMENTED();
        break;
      }

      default: {
        UNREACHABLE();
        break;
      }
    }
  } else {
    // by register
    Register rs = instr->RsField();
    shift_amount = get_register(rs) &0xff;
    switch (shift) {
      case ASR: {
        if (shift_amount == 0) {
          *carry_out = c_flag_;
        } else if (shift_amount < 32) {
          result >>= (shift_amount - 1);
          *carry_out = (result & 1) == 1;
          result >>= 1;
        } else {
          ASSERT(shift_amount >= 32);
          if (result < 0) {
            *carry_out = true;
            result = 0xffffffff;
          } else {
            *carry_out = false;
            result = 0;
          }
        }
        break;
      }

      case LSL: {
        if (shift_amount == 0) {
          *carry_out = c_flag_;
        } else if (shift_amount < 32) {
          result <<= (shift_amount - 1);
          *carry_out = (result < 0);
          result <<= 1;
        } else if (shift_amount == 32) {
          *carry_out = (result & 1) == 1;
          result = 0;
        } else {
          ASSERT(shift_amount > 32);
          *carry_out = false;
          result = 0;
        }
        break;
      }

      case LSR: {
        if (shift_amount == 0) {
          *carry_out = c_flag_;
        } else if (shift_amount < 32) {
          uint32_t uresult = static_cast<uint32_t>(result);
          uresult >>= (shift_amount - 1);
          *carry_out = (uresult & 1) == 1;
          uresult >>= 1;
          result = static_cast<int32_t>(uresult);
        } else if (shift_amount == 32) {
          *carry_out = (result < 0);
          result = 0;
        } else {
          *carry_out = false;
          result = 0;
        }
        break;
      }

      case ROR: {
        UNIMPLEMENTED();
        break;
      }

      default: {
        UNREACHABLE();
        break;
      }
    }
  }
  return result;
}


// Addressing Mode 1 - Data-processing operands:
// Get the value based on the shifter_operand with immediate.
int32_t Simulator::GetImm(Instr* instr, bool* carry_out) {
  int rotate = instr->RotateField() * 2;
  int immed8 = instr->Immed8Field();
  int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
  *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
  return imm;
}


static int count_bits(int bit_vector) {
  int count = 0;
  while (bit_vector != 0) {
    if ((bit_vector & 1) != 0) {
      count++;
    }
    bit_vector >>= 1;
  }
  return count;
}


// Addressing Mode 4 - Load and Store Multiple
void Simulator::HandleRList(Instr* instr, bool load) {
  Register rn = instr->RnField();
  int32_t rn_val = get_register(rn);
  int rlist = instr->RlistField();
  int num_regs = count_bits(rlist);

  uword address = 0;
  uword end_address = 0;
  switch (instr->PUField()) {
    case 0: {
      // Print("da");
      address = rn_val - (num_regs * 4) + 4;
      end_address = rn_val + 4;
      rn_val = rn_val - (num_regs * 4);
      break;
    }
    case 1: {
      // Print("ia");
      address = rn_val;
      end_address = rn_val + (num_regs * 4);
      rn_val = rn_val + (num_regs * 4);
      break;
    }
    case 2: {
      // Print("db");
      address = rn_val - (num_regs * 4);
      end_address = rn_val;
      rn_val = address;
      break;
    }
    case 3: {
      // Print("ib");
      address = rn_val + 4;
      end_address = rn_val + (num_regs * 4) + 4;
      rn_val = rn_val + (num_regs * 4);
      break;
    }
    default: {
      UNREACHABLE();
      break;
    }
  }
  if (IsIllegalAddress(address)) {
    HandleIllegalAccess(address, instr);
  } else {
    if (instr->HasW()) {
      set_register(rn, rn_val);
    }
    int reg = 0;
    while (rlist != 0) {
      if ((rlist & 1) != 0) {
        if (load) {
          set_register(static_cast<Register>(reg), ReadW(address, instr));
        } else {
          WriteW(address, get_register(static_cast<Register>(reg)), instr);
        }
        address += 4;
      }
      reg++;
      rlist >>= 1;
    }
    ASSERT(end_address == address);
  }
}


// Calls into the Dart runtime are based on this simple interface.
typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);


static void PrintExternalCallTrace(intptr_t external,
                                   NativeArguments arguments) {
  // TODO(regis): Do a reverse lookup on this address and print the symbol.
  UNIMPLEMENTED();
}


void Simulator::SupervisorCall(Instr* instr) {
  int svc = instr->SvcField();
  switch (svc) {
    case kRedirectionSvcCode: {
      SimulatorSetjmpBuffer buffer(this);

      if (!setjmp(buffer.buffer_)) {
        NativeArguments arguments;
        ASSERT(sizeof(NativeArguments) == 4*kWordSize);
        arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
        arguments.argc_tag_ = get_register(R1);
        arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
        arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));

        int32_t saved_lr = get_register(LR);
        Redirection* redirection = Redirection::FromSvcInstruction(instr);
        intptr_t external =
            reinterpret_cast<intptr_t>(redirection->external_function());
        SimulatorRuntimeCall target =
            reinterpret_cast<SimulatorRuntimeCall>(external);
        if (FLAG_trace_sim) {
          PrintExternalCallTrace(external, arguments);
        }
        target(arguments);

        // Zap caller-saved registers, since the actual runtime call could have
        // used them.
        set_register(R2, icount_);
        set_register(R3, icount_);
        set_register(IP, icount_);
        set_register(LR, icount_);
        float zap_fvalue = static_cast<float>(icount_);
        for (int i = S0; i <= S15; i++) {
          set_sregister(static_cast<SRegister>(i), zap_fvalue);
        }
#ifdef VFPv3_D32
        double zap_dvalue = static_cast<double>(icount_);
        for (int i = D16; i <= D31; i++) {
          set_dregister(static_cast<DRegister>(i), zap_dvalue);
        }
#endif  // VFPv3_D32

        // Zap result register pair R0:R1 and return.
        set_register(R0, icount_);
        set_register(R1, icount_);
        set_pc(saved_lr);
      }

      break;
    }
    case kBreakpointSvcCode: {
      SimulatorDebugger dbg(this);
      dbg.Stop(instr, "breakpoint");
      break;
    }
    case kStopMessageSvcCode: {
      SimulatorDebugger dbg(this);
      const char* message = *reinterpret_cast<const char**>(
          reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
      set_pc(get_pc() + Instr::kInstrSize);
      dbg.Stop(instr, message);
      break;
    }
    case kWordSpillMarkerSvcCode: {
      static StatsCounter counter_spill_w("Simulated word spills");
      counter_spill_w.Increment();
      break;
    }
    case kDWordSpillMarkerSvcCode: {
      static StatsCounter counter_spill_d("Simulated double word spills");
      counter_spill_d.Increment();
      break;
    }
    default: {
      UNREACHABLE();
      break;
    }
  }
}


// Handle execution based on instruction types.

// Instruction types 0 and 1 are both rolled into one function because they
// only differ in the handling of the shifter_operand.
void Simulator::DecodeType01(Instr* instr) {
  if (!instr->IsDataProcessing()) {
    // miscellaneous, multiply, sync primitives, extra loads and stores.
    if (instr->IsMiscellaneous()) {
      switch (instr->Bits(4, 3)) {
        case 1: {
          ASSERT(instr->Bits(21, 2) == 0x3);
          // Format(instr, "clz'cond 'rd, 'rm");
          Register rm = instr->RmField();
          Register rd = instr->RdField();
          int32_t rm_val = get_register(rm);
          int32_t rd_val = 0;
          if (rm_val != 0) {
            while (rm_val > 0) {
              rd_val++;
              rm_val <<= 1;
            }
          } else {
            rd_val = 32;
          }
          set_register(rd, rd_val);
          break;
        }
        case 3: {
          ASSERT(instr->Bits(21, 2) == 0x1);
          // Format(instr, "blx'cond 'rm");
          Register rm = instr->RmField();
          int32_t rm_val = get_register(rm);
          intptr_t pc = get_pc();
          set_register(LR, pc + Instr::kInstrSize);
          set_pc(rm_val);
          break;
        }
        case 7: {
          if (instr->Bits(21, 2) == 0x1) {
            // Format(instr, "bkpt #'imm12_4");
            SimulatorDebugger dbg(this);
            set_pc(get_pc() + Instr::kInstrSize);
            char buffer[32];
            snprintf(buffer, sizeof(buffer), "bkpt #0x%x", instr->BkptField());
            dbg.Stop(instr, buffer);
          } else {
             // Format(instr, "smc'cond");
            UNIMPLEMENTED();
          }
          break;
        }
        default: {
          UNIMPLEMENTED();
          break;
        }
      }
    } else if (instr->IsMultiplyOrSyncPrimitive()) {
      if (instr->Bit(24) == 0) {
        // multiply instructions.
        Register rn = instr->RnField();
        Register rd = instr->RdField();
        Register rs = instr->RsField();
        Register rm = instr->RmField();
        int32_t rm_val = get_register(rm);
        int32_t rs_val = get_register(rs);
        int32_t rd_val = 0;
        switch (instr->Bits(21, 3)) {
          case 1:
            // Registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
            // Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
          case 3: {
            // Registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
            // Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
            rd_val = get_register(rd);
            // fall through
          }
          case 0: {
            // Registers rd, rn, rm are encoded as rn, rm, rs.
            // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
            int32_t alu_out = rm_val * rs_val;
            if (instr->Bits(21, 3) == 3) {  // mls
              alu_out = -alu_out;
            }
            alu_out += rd_val;
            set_register(rn, alu_out);
            if (instr->HasS()) {
              SetNZFlags(alu_out);
            }
            break;
          }
          case 4: {
            // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
            // Format(instr, "umull'cond's 'rd, 'rn, 'rm, 'rs");
            uint64_t left_op  = static_cast<uint32_t>(rm_val);
            uint64_t right_op = static_cast<uint32_t>(rs_val);
            uint64_t result = left_op * right_op;
            int32_t hi_res = Utils::High32Bits(result);
            int32_t lo_res = Utils::Low32Bits(result);
            set_register(rd, lo_res);
            set_register(rn, hi_res);
            if (instr->HasS()) {
              if (lo_res != 0) {
                // Collapse bits 0..31 into bit 32 so that 32-bit Z check works.
                hi_res |= 1;
              }
              ASSERT((result == 0) == (hi_res == 0));  // Z bit
              ASSERT(((result & (1LL << 63)) != 0) == (hi_res < 0));  // N bit
              SetNZFlags(hi_res);
            }
            break;
          }
          default: {
            UNIMPLEMENTED();
            break;
          }
        }
      } else {
        // synchronization primitives
        Register rd = instr->RdField();
        Register rn = instr->RnField();
        uword addr = get_register(rn);
        switch (instr->Bits(20, 4)) {
          case 8: {
            // Format(instr, "strex'cond 'rd, 'rm, ['rn]");
            if (IsIllegalAddress(addr)) {
              HandleIllegalAccess(addr, instr);
            } else {
              Register rm = instr->RmField();
              set_register(rd, WriteExclusiveW(addr, get_register(rm), instr));
            }
            break;
          }
          case 9: {
            // Format(instr, "ldrex'cond 'rd, ['rn]");
            if (IsIllegalAddress(addr)) {
              HandleIllegalAccess(addr, instr);
            } else {
              set_register(rd, ReadExclusiveW(addr, instr));
            }
            break;
          }
          default: {
            UNIMPLEMENTED();
            break;
          }
        }
      }
    } else if (instr->Bit(25) == 1) {
      // 16-bit immediate loads, msr (immediate), and hints
      switch (instr->Bits(20, 5)) {
        case 16:
        case 20: {
          uint16_t imm16 = instr->MovwField();
          Register rd = instr->RdField();
          if (instr->Bit(22) == 0) {
            // Format(instr, "movw'cond 'rd, #'imm4_12");
            set_register(rd, imm16);
          } else {
            // Format(instr, "movt'cond 'rd, #'imm4_12");
            set_register(rd, (get_register(rd) & 0xffff) | (imm16 << 16));
          }
          break;
        }
        case 18: {
          if ((instr->Bits(16, 4) == 0) && (instr->Bits(0, 8) == 0)) {
            // Format(instr, "nop'cond");
          } else {
            UNIMPLEMENTED();
          }
          break;
        }
        default: {
          UNIMPLEMENTED();
          break;
        }
      }
    } else {
      // extra load/store instructions
      Register rd = instr->RdField();
      Register rn = instr->RnField();
      int32_t rn_val = get_register(rn);
      uword addr = 0;
      bool write_back = false;
      if (instr->Bit(22) == 0) {
        Register rm = instr->RmField();
        int32_t rm_val = get_register(rm);
        switch (instr->PUField()) {
          case 0: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn], -'rm");
            ASSERT(!instr->HasW());
            addr = rn_val;
            rn_val -= rm_val;
            write_back = true;
            break;
          }
          case 1: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn], +'rm");
            ASSERT(!instr->HasW());
            addr = rn_val;
            rn_val += rm_val;
            write_back = true;
            break;
          }
          case 2: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn, -'rm]'w");
            rn_val -= rm_val;
            addr = rn_val;
            write_back = instr->HasW();
            break;
          }
          case 3: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn, +'rm]'w");
            rn_val += rm_val;
            addr = rn_val;
            write_back = instr->HasW();
            break;
          }
          default: {
            // The PU field is a 2-bit field.
            UNREACHABLE();
            break;
          }
        }
      } else {
        int32_t imm_val = (instr->ImmedHField() << 4) | instr->ImmedLField();
        switch (instr->PUField()) {
          case 0: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn], #-'off8");
            ASSERT(!instr->HasW());
            addr = rn_val;
            rn_val -= imm_val;
            write_back = true;
            break;
          }
          case 1: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn], #+'off8");
            ASSERT(!instr->HasW());
            addr = rn_val;
            rn_val += imm_val;
            write_back = true;
            break;
          }
          case 2: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn, #-'off8]'w");
            rn_val -= imm_val;
            addr = rn_val;
            write_back = instr->HasW();
            break;
          }
          case 3: {
            // Format(instr, "'memop'cond'x 'rd2, ['rn, #+'off8]'w");
            rn_val += imm_val;
            addr = rn_val;
            write_back = instr->HasW();
            break;
          }
          default: {
            // The PU field is a 2-bit field.
            UNREACHABLE();
            break;
          }
        }
      }
      if (IsIllegalAddress(addr)) {
        HandleIllegalAccess(addr, instr);
      } else {
        if (write_back) {
          set_register(rn, rn_val);
        }
        if (!instr->HasSign()) {
          if (instr->HasL()) {
            uint16_t val = ReadHU(addr, instr);
            set_register(rd, val);
          } else {
            uint16_t val = get_register(rd);
            WriteH(addr, val, instr);
          }
        } else if (instr->HasL()) {
          if (instr->HasH()) {
            int16_t val = ReadH(addr, instr);
            set_register(rd, val);
          } else {
            int8_t val = ReadB(addr);
            set_register(rd, val);
          }
        } else if ((rd & 1) == 0) {
          Register rd1 = static_cast<Register>(rd | 1);
          ASSERT(rd1 < kNumberOfCpuRegisters);
          if (instr->HasH()) {
            int32_t val_low = get_register(rd);
            int32_t val_high = get_register(rd1);
            WriteW(addr, val_low, instr);
            WriteW(addr + 4, val_high, instr);
          } else {
            int32_t val_low = ReadW(addr, instr);
            int32_t val_high = ReadW(addr + 4, instr);
            set_register(rd, val_low);
            set_register(rd1, val_high);
          }
        } else {
          UNIMPLEMENTED();
        }
      }
    }
  } else {
    Register rd = instr->RdField();
    Register rn = instr->RnField();
    int32_t rn_val = get_register(rn);
    int32_t shifter_operand = 0;
    bool shifter_carry_out = 0;
    if (instr->TypeField() == 0) {
      shifter_operand = GetShiftRm(instr, &shifter_carry_out);
    } else {
      ASSERT(instr->TypeField() == 1);
      shifter_operand = GetImm(instr, &shifter_carry_out);
    }
    int32_t alu_out;

    switch (instr->OpcodeField()) {
      case AND: {
        // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "and'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val & shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        }
        break;
      }

      case EOR: {
        // Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "eor'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val ^ shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        }
        break;
      }

      case SUB: {
        // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "sub'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val - shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(!BorrowFrom(rn_val, shifter_operand));
          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
        }
        break;
      }

      case RSB: {
        // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "rsb'cond's 'rd, 'rn, 'imm");
        alu_out = shifter_operand - rn_val;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(!BorrowFrom(shifter_operand, rn_val));
          SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
        }
        break;
      }

      case ADD: {
        // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "add'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val + shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(CarryFrom(rn_val, shifter_operand));
          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
        }
        break;
      }

      case ADC: {
        // Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "adc'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val + shifter_operand + (c_flag_ ? 1 : 0);
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(CarryFrom(rn_val, shifter_operand));
          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
        }
        break;
      }

      case SBC: {
        // Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val - shifter_operand - (!c_flag_ ? 1 : 0);
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(!BorrowFrom(rn_val, shifter_operand));
          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
        }
        break;
      }

      case RSC: {
        // Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
        alu_out = shifter_operand - rn_val - (!c_flag_ ? 1 : 0);
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(!BorrowFrom(shifter_operand, rn_val));
          SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
        }
        break;
      }

      case TST: {
        if (instr->HasS()) {
          // Format(instr, "tst'cond 'rn, 'shift_rm");
          // Format(instr, "tst'cond 'rn, 'imm");
          alu_out = rn_val & shifter_operand;
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        } else {
          UNIMPLEMENTED();
        }
        break;
      }

      case TEQ: {
        if (instr->HasS()) {
          // Format(instr, "teq'cond 'rn, 'shift_rm");
          // Format(instr, "teq'cond 'rn, 'imm");
          alu_out = rn_val ^ shifter_operand;
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        } else {
          UNIMPLEMENTED();
        }
        break;
      }

      case CMP: {
        if (instr->HasS()) {
          // Format(instr, "cmp'cond 'rn, 'shift_rm");
          // Format(instr, "cmp'cond 'rn, 'imm");
          alu_out = rn_val - shifter_operand;
          SetNZFlags(alu_out);
          SetCFlag(!BorrowFrom(rn_val, shifter_operand));
          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
        } else {
          UNIMPLEMENTED();
        }
        break;
      }

      case CMN: {
        if (instr->HasS()) {
          // Format(instr, "cmn'cond 'rn, 'shift_rm");
          // Format(instr, "cmn'cond 'rn, 'imm");
          alu_out = rn_val + shifter_operand;
          SetNZFlags(alu_out);
          SetCFlag(CarryFrom(rn_val, shifter_operand));
          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
        } else {
          UNIMPLEMENTED();
        }
        break;
      }

      case ORR: {
        // Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "orr'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val | shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        }
        break;
      }

      case MOV: {
        // Format(instr, "mov'cond's 'rd, 'shift_rm");
        // Format(instr, "mov'cond's 'rd, 'imm");
        alu_out = shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        }
        break;
      }

      case BIC: {
        // Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");
        // Format(instr, "bic'cond's 'rd, 'rn, 'imm");
        alu_out = rn_val & ~shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        }
        break;
      }

      case MVN: {
        // Format(instr, "mvn'cond's 'rd, 'shift_rm");
        // Format(instr, "mvn'cond's 'rd, 'imm");
        alu_out = ~shifter_operand;
        set_register(rd, alu_out);
        if (instr->HasS()) {
          SetNZFlags(alu_out);
          SetCFlag(shifter_carry_out);
        }
        break;
      }

      default: {
        UNREACHABLE();
        break;
      }
    }
  }
}


void Simulator::DecodeType2(Instr* instr) {
  Register rd = instr->RdField();
  Register rn = instr->RnField();
  int32_t rn_val = get_register(rn);
  int32_t im_val = instr->Offset12Field();
  uword addr = 0;
  bool write_back = false;
  switch (instr->PUField()) {
    case 0: {
      // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
      ASSERT(!instr->HasW());
      addr = rn_val;
      rn_val -= im_val;
      write_back = true;
      break;
    }
    case 1: {
      // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
      ASSERT(!instr->HasW());
      addr = rn_val;
      rn_val += im_val;
      write_back = true;
      break;
    }
    case 2: {
      // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
      rn_val -= im_val;
      addr = rn_val;
      write_back = instr->HasW();
      break;
    }
    case 3: {
      // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
      rn_val += im_val;
      addr = rn_val;
      write_back = instr->HasW();
      break;
    }
    default: {
      UNREACHABLE();
      break;
    }
  }
  if (IsIllegalAddress(addr)) {
    HandleIllegalAccess(addr, instr);
  } else {
    if (write_back) {
      set_register(rn, rn_val);
    }
    if (instr->HasB()) {
      if (instr->HasL()) {
        unsigned char val = ReadBU(addr);
        set_register(rd, val);
      } else {
        unsigned char val = get_register(rd);
        WriteB(addr, val);
      }
    } else {
      if (instr->HasL()) {
        set_register(rd, ReadW(addr, instr));
      } else {
        WriteW(addr, get_register(rd), instr);
      }
    }
  }
}


void Simulator::DecodeType3(Instr* instr) {
  Register rd = instr->RdField();
  Register rn = instr->RnField();
  int32_t rn_val = get_register(rn);
  bool shifter_carry_out = 0;
  int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
  uword addr = 0;
  bool write_back = false;
  switch (instr->PUField()) {
    case 0: {
      // Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
      ASSERT(!instr->HasW());
      addr = rn_val;
      rn_val -= shifter_operand;
      write_back = true;
      break;
    }
    case 1: {
      // Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
      ASSERT(!instr->HasW());
      addr = rn_val;
      rn_val += shifter_operand;
      write_back = true;
      break;
    }
    case 2: {
      // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
      rn_val -= shifter_operand;
      addr = rn_val;
      write_back = instr->HasW();
      break;
    }
    case 3: {
      // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
      rn_val += shifter_operand;
      addr = rn_val;
      write_back = instr->HasW();
      break;
    }
    default: {
      UNREACHABLE();
      break;
    }
  }
  if (IsIllegalAddress(addr)) {
    HandleIllegalAccess(addr, instr);
  } else {
    if (write_back) {
      set_register(rn, rn_val);
    }
    if (instr->HasB()) {
      if (instr->HasL()) {
        unsigned char val = ReadBU(addr);
        set_register(rd, val);
      } else {
        unsigned char val = get_register(rd);
        WriteB(addr, val);
      }
    } else {
      if (instr->HasL()) {
        set_register(rd, ReadW(addr, instr));
      } else {
        WriteW(addr, get_register(rd), instr);
      }
    }
  }
}


void Simulator::DecodeType4(Instr* instr) {
  ASSERT(instr->Bit(22) == 0);  // only allowed to be set in privileged mode
  if (instr->HasL()) {
    // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
    HandleRList(instr, true);
  } else {
    // Format(instr, "stm'cond'pu 'rn'w, 'rlist");
    HandleRList(instr, false);
  }
}


void Simulator::DecodeType5(Instr* instr) {
  // Format(instr, "b'l'cond 'target");
  int off = (instr->SImmed24Field() << 2) + 8;
  intptr_t pc = get_pc();
  if (instr->HasLink()) {
    set_register(LR, pc + Instr::kInstrSize);
  }
  set_pc(pc+off);
}


void Simulator::DecodeType6(Instr* instr) {
  if (instr->IsVFPDoubleTransfer()) {
    Register rd = instr->RdField();
    Register rn = instr->RnField();
    if (instr->Bit(8) == 0) {
      SRegister sm = instr->SmField();
      SRegister sm1 = static_cast<SRegister>(sm + 1);
      ASSERT(sm1 < kNumberOfSRegisters);
      if (instr->Bit(20) == 1) {
        // Format(instr, "vmovrrs'cond 'rd, 'rn, {'sm', 'sm1}");
        set_register(rd, bit_cast<int32_t, float>(get_sregister(sm)));
        set_register(rn, bit_cast<int32_t, float>(get_sregister(sm1)));
      } else {
        // Format(instr, "vmovsrr'cond {'sm, 'sm1}, 'rd', 'rn");
        set_sregister(sm, bit_cast<float, int32_t>(get_register(rd)));
        set_sregister(sm1, bit_cast<float, int32_t>(get_register(rn)));
      }
    } else {
      DRegister dm = instr->DmField();
      if (instr->Bit(20) == 1) {
        // Format(instr, "vmovrrd'cond 'rd, 'rn, 'dm");
        int64_t dm_val = bit_cast<int64_t, double>(get_dregister(dm));
        set_register(rd, Utils::Low32Bits(dm_val));
        set_register(rn, Utils::High32Bits(dm_val));
      } else {
        // Format(instr, "vmovdrr'cond 'dm, 'rd, 'rn");
        int64_t dm_val = Utils::LowHighTo64Bits(get_register(rd),
                                                get_register(rn));
        set_dregister(dm, bit_cast<double, int64_t>(dm_val));
      }
    }
  } else if (instr-> IsVFPLoadStore()) {
    Register rn = instr->RnField();
    int32_t addr = get_register(rn);
    int32_t imm_val = instr->Bits(0, 8) << 2;
    if (instr->Bit(23) == 1) {
      addr += imm_val;
    } else {
      addr -= imm_val;
    }
    if (IsIllegalAddress(addr)) {
      HandleIllegalAccess(addr, instr);
    } else {
      if (instr->Bit(8) == 0) {
        SRegister sd = instr->SdField();
        if (instr->Bit(20) == 1) {  // vldrs
          // Format(instr, "vldrs'cond 'sd, ['rn, #+'off10]");
          // Format(instr, "vldrs'cond 'sd, ['rn, #-'off10]");
          set_sregister(sd, bit_cast<float, int32_t>(ReadW(addr, instr)));
        } else {  // vstrs
          // Format(instr, "vstrs'cond 'sd, ['rn, #+'off10]");
          // Format(instr, "vstrs'cond 'sd, ['rn, #-'off10]");
          WriteW(addr, bit_cast<int32_t, float>(get_sregister(sd)), instr);
        }
      } else {
        DRegister dd = instr->DdField();
        if (instr->Bit(20) == 1) {  // vldrd
          // Format(instr, "vldrd'cond 'dd, ['rn, #+'off10]");
          // Format(instr, "vldrd'cond 'dd, ['rn, #-'off10]");
          int64_t dd_val = Utils::LowHighTo64Bits(ReadW(addr, instr),
                                                  ReadW(addr + 4, instr));
          set_dregister(dd, bit_cast<double, int64_t>(dd_val));
        } else {  // vstrd
          // Format(instr, "vstrd'cond 'dd, ['rn, #+'off10]");
          // Format(instr, "vstrd'cond 'dd, ['rn, #-'off10]");
          int64_t dd_val = bit_cast<int64_t, double>(get_dregister(dd));
          WriteW(addr, Utils::Low32Bits(dd_val), instr);
          WriteW(addr + 4, Utils::High32Bits(dd_val), instr);
        }
      }
    }
  } else {
    UNIMPLEMENTED();
  }
}


void Simulator::DecodeType7(Instr* instr) {
  if (instr->Bit(24) == 1) {
    // Format(instr, "svc #'svc");
    SupervisorCall(instr);
  } else if (instr->IsVFPDataProcessingOrSingleTransfer()) {
    if (instr->Bit(4) == 0) {
      // VFP Data Processing
      SRegister sd;
      SRegister sn;
      SRegister sm;
      DRegister dd;
      DRegister dn;
      DRegister dm;
      if (instr->Bit(8) == 0) {
        sd = instr->SdField();
        sn = instr->SnField();
        sm = instr->SmField();
        dd = kNoDRegister;
        dn = kNoDRegister;
        dm = kNoDRegister;
      } else {
        sd = kNoSRegister;
        sn = kNoSRegister;
        sm = kNoSRegister;
        dd = instr->DdField();
        dn = instr->DnField();
        dm = instr->DmField();
      }
      switch (instr->Bits(20, 4) & 0xb) {
        case 1:  // vnmla, vnmls, vnmul
        default: {
          UNIMPLEMENTED();
          break;
        }
        case 0: {  // vmla, vmls floating-point
          if (instr->Bit(8) == 0) {
            float addend = get_sregister(sn) * get_sregister(sm);
            float sd_val = get_sregister(sd);
            if (instr->Bit(6) == 0) {
              // Format(instr, "vmlas'cond 'sd, 'sn, 'sm");
            } else {
              // Format(instr, "vmlss'cond 'sd, 'sn, 'sm");
              addend = -addend;
            }
            set_sregister(sd, sd_val + addend);
          } else {
            double addend = get_dregister(dn) * get_dregister(dm);
            double dd_val = get_dregister(dd);
            if (instr->Bit(6) == 0) {
              // Format(instr, "vmlad'cond 'dd, 'dn, 'dm");
            } else {
              // Format(instr, "vmlsd'cond 'dd, 'dn, 'dm");
              addend = -addend;
            }
            set_dregister(dd, dd_val + addend);
          }
          break;
        }
        case 2: {  // vmul
          if (instr->Bit(8) == 0) {
            // Format(instr, "vmuls'cond 'sd, 'sn, 'sm");
            set_sregister(sd, get_sregister(sn) * get_sregister(sm));
          } else {
            // Format(instr, "vmuld'cond 'dd, 'dn, 'dm");
            set_dregister(dd, get_dregister(dn) * get_dregister(dm));
          }
          break;
        }
        case 8: {  // vdiv
          if (instr->Bit(8) == 0) {
            // Format(instr, "vdivs'cond 'sd, 'sn, 'sm");
            set_sregister(sd, get_sregister(sn) / get_sregister(sm));
          } else {
            // Format(instr, "vdivd'cond 'dd, 'dn, 'dm");
            set_dregister(dd, get_dregister(dn) / get_dregister(dm));
          }
          break;
        }
        case 3: {  // vadd, vsub floating-point
          if (instr->Bit(8) == 0) {
            if (instr->Bit(6) == 0) {
              // Format(instr, "vadds'cond 'sd, 'sn, 'sm");
              set_sregister(sd, get_sregister(sn) + get_sregister(sm));
            } else {
              // Format(instr, "vsubs'cond 'sd, 'sn, 'sm");
              set_sregister(sd, get_sregister(sn) - get_sregister(sm));
            }
          } else {
            if (instr->Bit(6) == 0) {
              // Format(instr, "vaddd'cond 'dd, 'dn, 'dm");
              set_dregister(dd, get_dregister(dn) + get_dregister(dm));
            } else {
              // Format(instr, "vsubd'cond 'dd, 'dn, 'dm");
              set_dregister(dd, get_dregister(dn) - get_dregister(dm));
            }
          }
          break;
        }
        case 0xb: {  // Other VFP data-processing instructions
          if (instr->Bit(6) == 0) {  // vmov immediate
            if (instr->Bit(8) == 0) {
              // Format(instr, "vmovs'cond 'sd, #'immf");
              set_sregister(sd, instr->ImmFloatField());
            } else {
              // Format(instr, "vmovd'cond 'dd, #'immd");
              set_dregister(dd, instr->ImmDoubleField());
            }
            break;
          }
          switch (instr->Bits(16, 4)) {
            case 0: {  // vmov immediate, vmov register, vabs
              switch (instr->Bits(6, 2)) {
                case 1: {  // vmov register
                  if (instr->Bit(8) == 0) {
                    // Format(instr, "vmovs'cond 'sd, 'sm");
                    set_sregister(sd, get_sregister(sm));
                  } else {
                    // Format(instr, "vmovd'cond 'dd, 'dm");
                    set_dregister(dd, get_dregister(dm));
                  }
                  break;
                }
                case 3: {  // vabs
                  if (instr->Bit(8) == 0) {
                    // Format(instr, "vabss'cond 'sd, 'sm");
                    set_sregister(sd, fabsf(get_sregister(sm)));
                  } else {
                    // Format(instr, "vabsd'cond 'dd, 'dm");
                    set_dregister(dd, fabs(get_dregister(dm)));
                  }
                  break;
                }
                default: {
                  UNIMPLEMENTED();
                  break;
                }
              }
              break;
            }
            case 1: {  // vneg, vsqrt
              switch (instr->Bits(6, 2)) {
                case 1: {  // vneg
                  if (instr->Bit(8) == 0) {
                    // Format(instr, "vnegs'cond 'sd, 'sm");
                    set_sregister(sd, -get_sregister(sm));
                  } else {
                    // Format(instr, "vnegd'cond 'dd, 'dm");
                    set_dregister(dd, -get_dregister(dm));
                  }
                  break;
                }
                case 3: {  // vsqrt
                  if (instr->Bit(8) == 0) {
                    // Format(instr, "vsqrts'cond 'sd, 'sm");
                    set_sregister(sd, sqrtf(get_sregister(sm)));
                  } else {
                    // Format(instr, "vsqrtd'cond 'dd, 'dm");
                    set_dregister(dd, sqrt(get_dregister(dm)));
                  }
                  break;
                }
                default: {
                  UNIMPLEMENTED();
                  break;
                }
              }
              break;
            }
            case 4:  // vcmp, vcmpe
            case 5: {  // vcmp #0.0, vcmpe #0.0
              if (instr->Bit(7) == 1) {  // vcmpe
                UNIMPLEMENTED();
              } else {
                fp_n_flag_ = false;
                fp_z_flag_ = false;
                fp_c_flag_ = false;
                fp_v_flag_ = false;
                if (instr->Bit(8) == 0) {  // vcmps
                  float sd_val = get_sregister(sd);
                  float sm_val;
                  if (instr->Bit(16) == 0) {
                    // Format(instr, "vcmps'cond 'sd, 'sm");
                    sm_val = get_sregister(sm);
                  } else {
                    // Format(instr, "vcmps'cond 'sd, #0.0");
                    sm_val = 0.0f;
                  }
                  if (isnan(sd_val) || isnan(sm_val)) {
                    fp_c_flag_ = true;
                    fp_v_flag_ = true;
                  } else if (sd_val == sm_val) {
                    fp_z_flag_ = true;
                    fp_c_flag_ = true;
                  } else if (sd_val < sm_val) {
                    fp_n_flag_ = true;
                  } else {
                    fp_c_flag_ = true;
                  }
                } else {  // vcmpd
                  double dd_val = get_dregister(dd);
                  double dm_val;
                  if (instr->Bit(16) == 0) {
                    // Format(instr, "vcmpd'cond 'dd, 'dm");
                    dm_val = get_dregister(dm);
                  } else {
                    // Format(instr, "vcmpd'cond 'dd, #0.0");
                    dm_val = 0.0;
                  }
                  if (isnan(dd_val) || isnan(dm_val)) {
                    fp_c_flag_ = true;
                    fp_v_flag_ = true;
                  } else if (dd_val == dm_val) {
                    fp_z_flag_ = true;
                    fp_c_flag_ = true;
                  } else if (dd_val < dm_val) {
                    fp_n_flag_ = true;
                  } else {
                    fp_c_flag_ = true;
                  }
                }
              }
              break;
            }
            case 7: {  // vcvt between double-precision and single-precision
              if (instr->Bit(8) == 0) {
                // Format(instr, "vcvtds'cond 'dd, 'sm");
                dd = instr->DdField();
                set_dregister(dd, static_cast<double>(get_sregister(sm)));
              } else {
                // Format(instr, "vcvtsd'cond 'sd, 'dm");
                sd = instr->SdField();
                set_sregister(sd, static_cast<float>(get_dregister(dm)));
              }
              break;
            }
            case 8: {  // vcvt, vcvtr between floating-point and integer
              sm = instr->SmField();
              float sm_val = get_sregister(sm);
              uint32_t ud_val = 0;
              int32_t id_val = 0;
              if (instr->Bit(7) == 0) {  // vcvtsu, vcvtdu
                ud_val = bit_cast<uint32_t, float>(sm_val);
              } else {  // vcvtsi, vcvtdi
                id_val = bit_cast<int32_t, float>(sm_val);
              }
              if (instr->Bit(8) == 0) {
                float sd_val;
                if (instr->Bit(7) == 0) {
                  // Format(instr, "vcvtsu'cond 'sd, 'sm");
                  sd_val = static_cast<float>(ud_val);
                } else {
                  // Format(instr, "vcvtsi'cond 'sd, 'sm");
                  sd_val = static_cast<float>(id_val);
                }
                set_sregister(sd, sd_val);
              } else {
                double dd_val;
                if (instr->Bit(7) == 0) {
                  // Format(instr, "vcvtdu'cond 'dd, 'sm");
                  dd_val = static_cast<double>(ud_val);
                } else {
                  // Format(instr, "vcvtdi'cond 'dd, 'sm");
                  dd_val = static_cast<double>(id_val);
                }
                set_dregister(dd, dd_val);
              }
              break;
            }
            case 12:
            case 13: {  // vcvt, vcvtr between floating-point and integer
              // We do not need to record exceptions in the FPSCR cumulative
              // flags, because we do not use them.
              if (instr->Bit(7) == 0) {
                // We only support round-to-zero mode
                UNIMPLEMENTED();
                break;
              }
              int32_t id_val = 0;
              uint32_t ud_val = 0;
              if (instr->Bit(8) == 0) {
                float sm_val = get_sregister(sm);
                if (instr->Bit(16) == 0) {
                  // Format(instr, "vcvtus'cond 'sd, 'sm");
                  if (sm_val >= INT_MAX) {
                    ud_val = INT_MAX;
                  } else if (sm_val > 0.0) {
                    ud_val = static_cast<uint32_t>(sm_val);
                  }
                } else {
                  // Format(instr, "vcvtis'cond 'sd, 'sm");
                  if (sm_val <= INT_MIN) {
                    id_val = INT_MIN;
                  } else if (sm_val >= INT_MAX) {
                    id_val = INT_MAX;
                  } else {
                    id_val = static_cast<int32_t>(sm_val);
                  }
                  ASSERT((id_val >= 0) || !(sm_val >= 0.0));
                }
              } else {
                sd = instr->SdField();
                double dm_val = get_dregister(dm);
                if (instr->Bit(16) == 0) {
                  // Format(instr, "vcvtud'cond 'sd, 'dm");
                  if (dm_val >= INT_MAX) {
                    ud_val = INT_MAX;
                  } else if (dm_val > 0.0) {
                    ud_val = static_cast<uint32_t>(dm_val);
                  }
                } else {
                  // Format(instr, "vcvtid'cond 'sd, 'dm");
                  if (dm_val <= INT_MIN) {
                    id_val = INT_MIN;
                  } else if (dm_val >= INT_MAX) {
                    id_val = INT_MAX;
                  } else {
                    id_val = static_cast<int32_t>(dm_val);
                  }
                  ASSERT((id_val >= 0) || !(dm_val >= 0.0));
                }
              }
              float sd_val;
              if (instr->Bit(16) == 0) {
                sd_val = bit_cast<float, uint32_t>(ud_val);
              } else {
                sd_val = bit_cast<float, int32_t>(id_val);
              }
              set_sregister(sd, sd_val);
              break;
            }
            case 2:  // vcvtb, vcvtt
            case 3:  // vcvtb, vcvtt
            case 9:  // undefined
            case 10:  // vcvt between floating-point and fixed-point
            case 11:  // vcvt between floating-point and fixed-point
            case 14:  // vcvt between floating-point and fixed-point
            case 15:  // vcvt between floating-point and fixed-point
            default: {
              UNIMPLEMENTED();
              break;
            }
          }
        }
        break;
      }
    } else {
      // 8, 16, or 32-bit Transfer between ARM Core and VFP
      if ((instr->Bits(21, 3) == 0) && (instr->Bit(8) == 0)) {
        Register rd = instr->RdField();
        SRegister sn = instr->SnField();
        if (instr->Bit(20) == 0) {
          // Format(instr, "vmovs'cond 'sn, 'rd");
          set_sregister(sn, bit_cast<float, int32_t>(get_register(rd)));
        } else {
          // Format(instr, "vmovr'cond 'rd, 'sn");
          set_register(rd, bit_cast<int32_t, float>(get_sregister(sn)));
        }
      } else if ((instr->Bits(20, 4) == 0xf) && (instr->Bit(8) == 0) &&
                 (instr->Bits(12, 4) == 0xf)) {
        // Format(instr, "vmstat'cond");
        n_flag_ = fp_n_flag_;
        z_flag_ = fp_z_flag_;
        c_flag_ = fp_c_flag_;
        v_flag_ = fp_v_flag_;
      } else {
        UNIMPLEMENTED();
      }
    }
  } else {
    UNIMPLEMENTED();
  }
}


// Executes the current instruction.
void Simulator::InstructionDecode(Instr* instr) {
  pc_modified_ = false;
  if (FLAG_trace_sim) {
    const uword start = reinterpret_cast<uword>(instr);
    const uword end = start + Instr::kInstrSize;
    Disassembler::Disassemble(start, end);
  }
  if (instr->ConditionField() == kSpecialCondition) {
    if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) {
      // Format(instr, "clrex");
      ClearExclusive();
    } else {
      UNIMPLEMENTED();
    }
  } else if (ConditionallyExecute(instr)) {
    switch (instr->TypeField()) {
      case 0:
      case 1: {
        DecodeType01(instr);
        break;
      }
      case 2: {
        DecodeType2(instr);
        break;
      }
      case 3: {
        DecodeType3(instr);
        break;
      }
      case 4: {
        DecodeType4(instr);
        break;
      }
      case 5: {
        DecodeType5(instr);
        break;
      }
      case 6: {
        DecodeType6(instr);
        break;
      }
      case 7: {
        DecodeType7(instr);
        break;
      }
      default: {
        UNIMPLEMENTED();
        break;
      }
    }
  }
  if (!pc_modified_) {
    set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
  }
}


void Simulator::Execute() {
  static StatsCounter counter_instructions("Simulated instructions");

  // Get the PC to simulate. Cannot use the accessor here as we need the
  // raw PC value and not the one used as input to arithmetic instructions.
  uword program_counter = get_pc();

  if (FLAG_stop_sim_at == 0) {
    // Fast version of the dispatch loop without checking whether the simulator
    // should be stopping at a particular executed instruction.
    while (program_counter != kEndSimulatingPC) {
      Instr* instr = reinterpret_cast<Instr*>(program_counter);
      icount_++;
      counter_instructions.Increment();
      if (IsIllegalAddress(program_counter)) {
        HandleIllegalAccess(program_counter, instr);
      } else {
        InstructionDecode(instr);
      }
      program_counter = get_pc();
    }
  } else {
    // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
    // we reach the particular instruction count.
    while (program_counter != kEndSimulatingPC) {
      Instr* instr = reinterpret_cast<Instr*>(program_counter);
      icount_++;
      counter_instructions.Increment();
      if (icount_ == FLAG_stop_sim_at) {
        SimulatorDebugger dbg(this);
        dbg.Debug();
      } else if (IsIllegalAddress(program_counter)) {
        HandleIllegalAccess(program_counter, instr);
      } else {
        InstructionDecode(instr);
      }
      program_counter = get_pc();
    }
  }
}


int64_t Simulator::Call(int32_t entry,
                        int32_t parameter0,
                        int32_t parameter1,
                        int32_t parameter2,
                        int32_t parameter3,
                        int32_t parameter4) {
  // Save the SP register before the call so we can restore it.
  int32_t sp_before_call = get_register(SP);

  // Setup parameters.
  set_register(R0, parameter0);
  set_register(R1, parameter1);
  set_register(R2, parameter2);
  set_register(R3, parameter3);

  // Reserve room for one stack parameter.
  int32_t stack_pointer = sp_before_call;
  stack_pointer -= kWordSize;

  // Make sure the activation frames are properly aligned.
  static const int kFrameAlignment = OS::ActivationFrameAlignment();
  if (kFrameAlignment > 0) {
    stack_pointer = Utils::RoundDown(stack_pointer, kFrameAlignment);
  }

  // Write the fourth parameter to the stack and update register SP.
  *reinterpret_cast<int32_t*>(stack_pointer) = parameter4;
  set_register(SP, stack_pointer);

  // Prepare to execute the code at entry.
  set_register(PC, entry);
  // Put down marker for end of simulation. The simulator will stop simulation
  // when the PC reaches this value. By saving the "end simulation" value into
  // the LR the simulation stops when returning to this call point.
  set_register(LR, kEndSimulatingPC);

  // Remember the values of callee-saved registers.
  // The code below assumes that r9 is not used as sb (static base) in
  // simulator code and therefore is regarded as a callee-saved register.
  int32_t r4_val = get_register(R4);
  int32_t r5_val = get_register(R5);
  int32_t r6_val = get_register(R6);
  int32_t r7_val = get_register(R7);
  int32_t r8_val = get_register(R8);
  int32_t r9_val = get_register(R9);
  int32_t r10_val = get_register(R10);
  int32_t r11_val = get_register(R11);

  // Setup the callee-saved registers with a known value. To be able to check
  // that they are preserved properly across JS execution.
  int32_t callee_saved_value = icount_;
  set_register(R4, callee_saved_value);
  set_register(R5, callee_saved_value);
  set_register(R6, callee_saved_value);
  set_register(R7, callee_saved_value);
  set_register(R8, callee_saved_value);
  set_register(R9, callee_saved_value);
  set_register(R10, callee_saved_value);
  set_register(R11, callee_saved_value);

  // Start the simulation
  Execute();

  // Check that the callee-saved registers have been preserved.
  ASSERT(callee_saved_value == get_register(R4));
  ASSERT(callee_saved_value == get_register(R5));
  ASSERT(callee_saved_value == get_register(R6));
  ASSERT(callee_saved_value == get_register(R7));
  ASSERT(callee_saved_value == get_register(R8));
  ASSERT(callee_saved_value == get_register(R9));
  ASSERT(callee_saved_value == get_register(R10));
  ASSERT(callee_saved_value == get_register(R11));

  // Restore callee-saved registers with the original value.
  set_register(R4, r4_val);
  set_register(R5, r5_val);
  set_register(R6, r6_val);
  set_register(R7, r7_val);
  set_register(R8, r8_val);
  set_register(R9, r9_val);
  set_register(R10, r10_val);
  set_register(R11, r11_val);

  // Restore the SP register and return R1:R0.
  set_register(SP, sp_before_call);
  return Utils::LowHighTo64Bits(get_register(R0), get_register(R1));
}


void Simulator::Longjmp(
    int32_t pc, int32_t sp, int32_t fp, const Instance& object) {
  set_register(SP, sp);
  set_register(FP, fp);
  set_register(PC, pc);
  SimulatorSetjmpBuffer* buf = last_setjmp_buffer();

  // Walk over all setjmp buffers (simulated --> C++ transitions)
  // and try to find the setjmp associated with the stack pointer.
  while (buf->link() != NULL && buf->link()->sp() <= sp) {
    buf = buf->link();
  }
  ASSERT(buf != NULL);

  // Clean up stack memory of C++ frames.
  // TODO(regis): Revisit.
  // isolate->PrepareForUnwinding(reinterpret_cast<uword>(buf));
  // isolate->ChangeStateToGeneratedCode();
  set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw()));
  buf->Longjmp();
}

}  // namespace dart

#endif  // !defined(HOST_ARCH_ARM)

#endif  // defined TARGET_ARCH_ARM
