// Copyright 2011 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.

#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <cmath>

#include "src/v8.h"

#if V8_TARGET_ARCH_MIPS64

#include "src/assembler.h"
#include "src/base/bits.h"
#include "src/disasm.h"
#include "src/mips64/constants-mips64.h"
#include "src/mips64/simulator-mips64.h"
#include "src/ostreams.h"

// Only build the simulator if not compiling for real MIPS hardware.
#if defined(USE_SIMULATOR)

namespace v8 {
namespace internal {

// Utils functions.
bool HaveSameSign(int64_t a, int64_t b) {
  return ((a ^ b) >= 0);
}


uint32_t get_fcsr_condition_bit(uint32_t cc) {
  if (cc == 0) {
    return 23;
  } else {
    return 24 + cc;
  }
}


static int64_t MultiplyHighSigned(int64_t u, int64_t v) {
  uint64_t u0, v0, w0;
  int64_t u1, v1, w1, w2, t;

  u0 = u & 0xffffffffL;
  u1 = u >> 32;
  v0 = v & 0xffffffffL;
  v1 = v >> 32;

  w0 = u0 * v0;
  t = u1 * v0 + (w0 >> 32);
  w1 = t & 0xffffffffL;
  w2 = t >> 32;
  w1 = u0 * v1 + w1;

  return u1 * v1 + w2 + (w1 >> 32);
}


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

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

  void Stop(Instruction* instr);
  void Debug();
  // Print all registers with a nice formatting.
  void PrintAllRegs();
  void PrintAllRegsIncludingFPU();

 private:
  // We set the breakpoint code to 0xfffff to easily recognize it.
  static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6;
  static const Instr kNopInstr =  0x0;

  Simulator* sim_;

  int64_t GetRegisterValue(int regnum);
  int64_t GetFPURegisterValue(int regnum);
  float GetFPURegisterValueFloat(int regnum);
  double GetFPURegisterValueDouble(int regnum);
  bool GetValue(const char* desc, int64_t* value);

  // Set or delete a breakpoint. Returns true if successful.
  bool SetBreakpoint(Instruction* breakpc);
  bool DeleteBreakpoint(Instruction* 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();
};


MipsDebugger::~MipsDebugger() {
}


#ifdef GENERATED_CODE_COVERAGE
static FILE* coverage_log = NULL;


static void InitializeCoverage() {
  char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
  if (file_name != NULL) {
    coverage_log = fopen(file_name, "aw+");
  }
}


void MipsDebugger::Stop(Instruction* instr) {
  // Get the stop code.
  uint32_t code = instr->Bits(25, 6);
  // Retrieve the encoded address, which comes just after this stop.
  char** msg_address =
    reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
  char* msg = *msg_address;
  DCHECK(msg != NULL);

  // Update this stop description.
  if (!watched_stops_[code].desc) {
    watched_stops_[code].desc = msg;
  }

  if (strlen(msg) > 0) {
    if (coverage_log != NULL) {
      fprintf(coverage_log, "%s\n", str);
      fflush(coverage_log);
    }
    // Overwrite the instruction and address with nops.
    instr->SetInstructionBits(kNopInstr);
    reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
  }
  // TODO(yuyin): 2 -> 3?
  sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstructionSize);
}


#else  // GENERATED_CODE_COVERAGE

#define UNSUPPORTED() printf("Unsupported instruction.\n");

static void InitializeCoverage() {}


void MipsDebugger::Stop(Instruction* instr) {
  // Get the stop code.
  uint32_t code = instr->Bits(25, 6);
  // Retrieve the encoded address, which comes just after this stop.
  char* msg = *reinterpret_cast<char**>(sim_->get_pc() +
      Instruction::kInstrSize);
  // Update this stop description.
  if (!sim_->watched_stops_[code].desc) {
    sim_->watched_stops_[code].desc = msg;
  }
  PrintF("Simulator hit %s (%u)\n", msg, code);
  // TODO(yuyin): 2 -> 3?
  sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstrSize);
  Debug();
}
#endif  // GENERATED_CODE_COVERAGE


int64_t MipsDebugger::GetRegisterValue(int regnum) {
  if (regnum == kNumSimuRegisters) {
    return sim_->get_pc();
  } else {
    return sim_->get_register(regnum);
  }
}


int64_t MipsDebugger::GetFPURegisterValue(int regnum) {
  if (regnum == kNumFPURegisters) {
    return sim_->get_pc();
  } else {
    return sim_->get_fpu_register(regnum);
  }
}


float MipsDebugger::GetFPURegisterValueFloat(int regnum) {
  if (regnum == kNumFPURegisters) {
    return sim_->get_pc();
  } else {
    return sim_->get_fpu_register_float(regnum);
  }
}


double MipsDebugger::GetFPURegisterValueDouble(int regnum) {
  if (regnum == kNumFPURegisters) {
    return sim_->get_pc();
  } else {
    return sim_->get_fpu_register_double(regnum);
  }
}


bool MipsDebugger::GetValue(const char* desc, int64_t* value) {
  int regnum = Registers::Number(desc);
  int fpuregnum = FPURegisters::Number(desc);

  if (regnum != kInvalidRegister) {
    *value = GetRegisterValue(regnum);
    return true;
  } else if (fpuregnum != kInvalidFPURegister) {
    *value = GetFPURegisterValue(fpuregnum);
    return true;
  } else if (strncmp(desc, "0x", 2) == 0) {
    return SScanF(desc + 2, "%" SCNx64,
                  reinterpret_cast<uint64_t*>(value)) == 1;
  } else {
    return SScanF(desc, "%" SCNu64, reinterpret_cast<uint64_t*>(value)) == 1;
  }
  return false;
}


bool MipsDebugger::SetBreakpoint(Instruction* 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 MipsDebugger::DeleteBreakpoint(Instruction* breakpc) {
  if (sim_->break_pc_ != NULL) {
    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
  }

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


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


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


void MipsDebugger::PrintAllRegs() {
#define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)

  PrintF("\n");
  // at, v0, a0.
  PrintF("%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
         REG_INFO(1), REG_INFO(2), REG_INFO(4));
  // v1, a1.
  PrintF("%34s\t%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
         "", REG_INFO(3), REG_INFO(5));
  // a2.
  PrintF("%34s\t%34s\t%3s: 0x%016lx %14ld\n", "", "", REG_INFO(6));
  // a3.
  PrintF("%34s\t%34s\t%3s: 0x%016lx %14ld\n", "", "", REG_INFO(7));
  PrintF("\n");
  // a4-t3, s0-s7
  for (int i = 0; i < 8; i++) {
    PrintF("%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
           REG_INFO(8+i), REG_INFO(16+i));
  }
  PrintF("\n");
  // t8, k0, LO.
  PrintF("%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
         REG_INFO(24), REG_INFO(26), REG_INFO(32));
  // t9, k1, HI.
  PrintF("%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
         REG_INFO(25), REG_INFO(27), REG_INFO(33));
  // sp, fp, gp.
  PrintF("%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
         REG_INFO(29), REG_INFO(30), REG_INFO(28));
  // pc.
  PrintF("%3s: 0x%016lx %14ld\t%3s: 0x%016lx %14ld\n",
         REG_INFO(31), REG_INFO(34));

#undef REG_INFO
#undef FPU_REG_INFO
}


void MipsDebugger::PrintAllRegsIncludingFPU() {
#define FPU_REG_INFO(n) FPURegisters::Name(n), \
        GetFPURegisterValue(n), \
        GetFPURegisterValueDouble(n)

  PrintAllRegs();

  PrintF("\n\n");
  // f0, f1, f2, ... f31.
  // TODO(plind): consider printing 2 columns for space efficiency.
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(0) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(1) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(2) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(3) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(4) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(5) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(6) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(7) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(8) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(9) );
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(10));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(11));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(12));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(13));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(14));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(15));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(16));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(17));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(18));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(19));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(20));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(21));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(22));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(23));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(24));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(25));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(26));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(27));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(28));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(29));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(30));
  PrintF("%3s: 0x%016lx %16.4e\n", FPU_REG_INFO(31));

#undef REG_INFO
#undef FPU_REG_INFO
}


void MipsDebugger::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];
  char* argv[3] = { cmd, arg1, arg2 };

  // 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 && (sim_->get_pc() != Simulator::end_sim_pc)) {
    if (last_pc != sim_->get_pc()) {
      disasm::NameConverter converter;
      disasm::Disassembler dasm(converter);
      // Use a reasonably large buffer.
      v8::internal::EmbeddedVector<char, 256> buffer;
      dasm.InstructionDecode(buffer,
                             reinterpret_cast<byte*>(sim_->get_pc()));
      PrintF("  0x%016lx  %s\n", sim_->get_pc(), buffer.start());
      last_pc = sim_->get_pc();
    }
    char* line = ReadLine("sim> ");
    if (line == NULL) {
      break;
    } else {
      char* last_input = sim_->last_debugger_input();
      if (strcmp(line, "\n") == 0 && last_input != NULL) {
        line = last_input;
      } else {
        // Ownership is transferred to sim_;
        sim_->set_last_debugger_input(line);
      }
      // Use sscanf to parse the individual parts of the command line. At the
      // moment no command expects more than two parameters.
      int argc = SScanF(line,
                        "%" XSTR(COMMAND_SIZE) "s "
                        "%" XSTR(ARG_SIZE) "s "
                        "%" XSTR(ARG_SIZE) "s",
                        cmd, arg1, arg2);
      if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
        Instruction* instr = reinterpret_cast<Instruction*>(sim_->get_pc());
        if (!(instr->IsTrap()) ||
            instr->InstructionBits() == rtCallRedirInstr) {
          sim_->InstructionDecode(
              reinterpret_cast<Instruction*>(sim_->get_pc()));
        } else {
          // Allow si to jump over generated breakpoints.
          PrintF("/!\\ Jumping over generated breakpoint.\n");
          sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
        }
      } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
        // Execute the one instruction we broke at with breakpoints disabled.
        sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
        // Leave the debugger shell.
        done = true;
      } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
        if (argc == 2) {
          int64_t value;
          double dvalue;
          if (strcmp(arg1, "all") == 0) {
            PrintAllRegs();
          } else if (strcmp(arg1, "allf") == 0) {
            PrintAllRegsIncludingFPU();
          } else {
            int regnum = Registers::Number(arg1);
            int fpuregnum = FPURegisters::Number(arg1);

            if (regnum != kInvalidRegister) {
              value = GetRegisterValue(regnum);
              PrintF("%s: 0x%08lx %ld \n", arg1, value, value);
            } else if (fpuregnum != kInvalidFPURegister) {
              value = GetFPURegisterValue(fpuregnum);
              dvalue = GetFPURegisterValueDouble(fpuregnum);
              PrintF("%3s: 0x%016lx %16.4e\n",
                     FPURegisters::Name(fpuregnum), value, dvalue);
            } else {
              PrintF("%s unrecognized\n", arg1);
            }
          }
        } else {
          if (argc == 3) {
            if (strcmp(arg2, "single") == 0) {
              int64_t value;
              float fvalue;
              int fpuregnum = FPURegisters::Number(arg1);

              if (fpuregnum != kInvalidFPURegister) {
                value = GetFPURegisterValue(fpuregnum);
                value &= 0xffffffffUL;
                fvalue = GetFPURegisterValueFloat(fpuregnum);
                PrintF("%s: 0x%08lx %11.4e\n", arg1, value, fvalue);
              } else {
                PrintF("%s unrecognized\n", arg1);
              }
            } else {
              PrintF("print <fpu register> single\n");
            }
          } else {
            PrintF("print <register> or print <fpu register> single\n");
          }
        }
      } else if ((strcmp(cmd, "po") == 0)
                 || (strcmp(cmd, "printobject") == 0)) {
        if (argc == 2) {
          int64_t value;
          OFStream os(stdout);
          if (GetValue(arg1, &value)) {
            Object* obj = reinterpret_cast<Object*>(value);
            os << arg1 << ": \n";
#ifdef DEBUG
            obj->Print(os);
            os << "\n";
#else
            os << Brief(obj) << "\n";
#endif
          } else {
            os << arg1 << " unrecognized\n";
          }
        } else {
          PrintF("printobject <value>\n");
        }
      } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
        int64_t* cur = NULL;
        int64_t* end = NULL;
        int next_arg = 1;

        if (strcmp(cmd, "stack") == 0) {
          cur = reinterpret_cast<int64_t*>(sim_->get_register(Simulator::sp));
        } else {  // Command "mem".
          int64_t value;
          if (!GetValue(arg1, &value)) {
            PrintF("%s unrecognized\n", arg1);
            continue;
          }
          cur = reinterpret_cast<int64_t*>(value);
          next_arg++;
        }

        int64_t words;
        if (argc == next_arg) {
          words = 10;
        } else {
          if (!GetValue(argv[next_arg], &words)) {
            words = 10;
          }
        }
        end = cur + words;

        while (cur < end) {
          PrintF("  0x%012lx:  0x%016lx %14ld",
                 reinterpret_cast<intptr_t>(cur), *cur, *cur);
          HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
          int64_t value = *cur;
          Heap* current_heap = v8::internal::Isolate::Current()->heap();
          if (((value & 1) == 0) || current_heap->Contains(obj)) {
            PrintF(" (");
            if ((value & 1) == 0) {
              PrintF("smi %d", static_cast<int>(value >> 32));
            } else {
              obj->ShortPrint();
            }
            PrintF(")");
          }
          PrintF("\n");
          cur++;
        }

      } else if ((strcmp(cmd, "disasm") == 0) ||
                 (strcmp(cmd, "dpc") == 0) ||
                 (strcmp(cmd, "di") == 0)) {
        disasm::NameConverter converter;
        disasm::Disassembler dasm(converter);
        // Use a reasonably large buffer.
        v8::internal::EmbeddedVector<char, 256> buffer;

        byte* cur = NULL;
        byte* end = NULL;

        if (argc == 1) {
          cur = reinterpret_cast<byte*>(sim_->get_pc());
          end = cur + (10 * Instruction::kInstrSize);
        } else if (argc == 2) {
          int regnum = Registers::Number(arg1);
          if (regnum != kInvalidRegister || strncmp(arg1, "0x", 2) == 0) {
            // The argument is an address or a register name.
            int64_t value;
            if (GetValue(arg1, &value)) {
              cur = reinterpret_cast<byte*>(value);
              // Disassemble 10 instructions at <arg1>.
              end = cur + (10 * Instruction::kInstrSize);
            }
          } else {
            // The argument is the number of instructions.
            int64_t value;
            if (GetValue(arg1, &value)) {
              cur = reinterpret_cast<byte*>(sim_->get_pc());
              // Disassemble <arg1> instructions.
              end = cur + (value * Instruction::kInstrSize);
            }
          }
        } else {
          int64_t value1;
          int64_t value2;
          if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
            cur = reinterpret_cast<byte*>(value1);
            end = cur + (value2 * Instruction::kInstrSize);
          }
        }

        while (cur < end) {
          dasm.InstructionDecode(buffer, cur);
          PrintF("  0x%08lx  %s\n",
              reinterpret_cast<intptr_t>(cur), buffer.start());
          cur += Instruction::kInstrSize;
        }
      } else if (strcmp(cmd, "gdb") == 0) {
        PrintF("relinquishing control to gdb\n");
        v8::base::OS::DebugBreak();
        PrintF("regaining control from gdb\n");
      } else if (strcmp(cmd, "break") == 0) {
        if (argc == 2) {
          int64_t value;
          if (GetValue(arg1, &value)) {
            if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
              PrintF("setting breakpoint failed\n");
            }
          } else {
            PrintF("%s unrecognized\n", arg1);
          }
        } else {
          PrintF("break <address>\n");
        }
      } else if (strcmp(cmd, "del") == 0) {
        if (!DeleteBreakpoint(NULL)) {
          PrintF("deleting breakpoint failed\n");
        }
      } else if (strcmp(cmd, "flags") == 0) {
        PrintF("No flags on MIPS !\n");
      } else if (strcmp(cmd, "stop") == 0) {
        int64_t value;
        intptr_t stop_pc = sim_->get_pc() -
            2 * Instruction::kInstrSize;
        Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
        Instruction* msg_address =
          reinterpret_cast<Instruction*>(stop_pc +
              Instruction::kInstrSize);
        if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
          // Remove the current stop.
          if (sim_->IsStopInstruction(stop_instr)) {
            stop_instr->SetInstructionBits(kNopInstr);
            msg_address->SetInstructionBits(kNopInstr);
          } else {
            PrintF("Not at debugger stop.\n");
          }
        } else if (argc == 3) {
          // Print information about all/the specified breakpoint(s).
          if (strcmp(arg1, "info") == 0) {
            if (strcmp(arg2, "all") == 0) {
              PrintF("Stop information:\n");
              for (uint32_t i = kMaxWatchpointCode + 1;
                   i <= kMaxStopCode;
                   i++) {
                sim_->PrintStopInfo(i);
              }
            } else if (GetValue(arg2, &value)) {
              sim_->PrintStopInfo(value);
            } else {
              PrintF("Unrecognized argument.\n");
            }
          } else if (strcmp(arg1, "enable") == 0) {
            // Enable all/the specified breakpoint(s).
            if (strcmp(arg2, "all") == 0) {
              for (uint32_t i = kMaxWatchpointCode + 1;
                   i <= kMaxStopCode;
                   i++) {
                sim_->EnableStop(i);
              }
            } else if (GetValue(arg2, &value)) {
              sim_->EnableStop(value);
            } else {
              PrintF("Unrecognized argument.\n");
            }
          } else if (strcmp(arg1, "disable") == 0) {
            // Disable all/the specified breakpoint(s).
            if (strcmp(arg2, "all") == 0) {
              for (uint32_t i = kMaxWatchpointCode + 1;
                   i <= kMaxStopCode;
                   i++) {
                sim_->DisableStop(i);
              }
            } else if (GetValue(arg2, &value)) {
              sim_->DisableStop(value);
            } else {
              PrintF("Unrecognized argument.\n");
            }
          }
        } else {
          PrintF("Wrong usage. Use help command for more information.\n");
        }
      } else if ((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0)) {
        // Print registers and disassemble.
        PrintAllRegs();
        PrintF("\n");

        disasm::NameConverter converter;
        disasm::Disassembler dasm(converter);
        // Use a reasonably large buffer.
        v8::internal::EmbeddedVector<char, 256> buffer;

        byte* cur = NULL;
        byte* end = NULL;

        if (argc == 1) {
          cur = reinterpret_cast<byte*>(sim_->get_pc());
          end = cur + (10 * Instruction::kInstrSize);
        } else if (argc == 2) {
          int64_t value;
          if (GetValue(arg1, &value)) {
            cur = reinterpret_cast<byte*>(value);
            // no length parameter passed, assume 10 instructions
            end = cur + (10 * Instruction::kInstrSize);
          }
        } else {
          int64_t value1;
          int64_t value2;
          if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
            cur = reinterpret_cast<byte*>(value1);
            end = cur + (value2 * Instruction::kInstrSize);
          }
        }

        while (cur < end) {
          dasm.InstructionDecode(buffer, cur);
          PrintF("  0x%08lx  %s\n",
                 reinterpret_cast<intptr_t>(cur), buffer.start());
          cur += Instruction::kInstrSize;
        }
      } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
        PrintF("cont\n");
        PrintF("  continue execution (alias 'c')\n");
        PrintF("stepi\n");
        PrintF("  step one instruction (alias 'si')\n");
        PrintF("print <register>\n");
        PrintF("  print register content (alias 'p')\n");
        PrintF("  use register name 'all' to print all registers\n");
        PrintF("printobject <register>\n");
        PrintF("  print an object from a register (alias 'po')\n");
        PrintF("stack [<words>]\n");
        PrintF("  dump stack content, default dump 10 words)\n");
        PrintF("mem <address> [<words>]\n");
        PrintF("  dump memory content, default dump 10 words)\n");
        PrintF("flags\n");
        PrintF("  print flags\n");
        PrintF("disasm [<instructions>]\n");
        PrintF("disasm [<address/register>]\n");
        PrintF("disasm [[<address/register>] <instructions>]\n");
        PrintF("  disassemble code, default is 10 instructions\n");
        PrintF("  from pc (alias 'di')\n");
        PrintF("gdb\n");
        PrintF("  enter gdb\n");
        PrintF("break <address>\n");
        PrintF("  set a break point on the address\n");
        PrintF("del\n");
        PrintF("  delete the breakpoint\n");
        PrintF("stop feature:\n");
        PrintF("  Description:\n");
        PrintF("    Stops are debug instructions inserted by\n");
        PrintF("    the Assembler::stop() function.\n");
        PrintF("    When hitting a stop, the Simulator will\n");
        PrintF("    stop and and give control to the Debugger.\n");
        PrintF("    All stop codes are watched:\n");
        PrintF("    - They can be enabled / disabled: the Simulator\n");
        PrintF("       will / won't stop when hitting them.\n");
        PrintF("    - The Simulator keeps track of how many times they \n");
        PrintF("      are met. (See the info command.) Going over a\n");
        PrintF("      disabled stop still increases its counter. \n");
        PrintF("  Commands:\n");
        PrintF("    stop info all/<code> : print infos about number <code>\n");
        PrintF("      or all stop(s).\n");
        PrintF("    stop enable/disable all/<code> : enables / disables\n");
        PrintF("      all or number <code> stop(s)\n");
        PrintF("    stop unstop\n");
        PrintF("      ignore the stop instruction at the current location\n");
        PrintF("      from now on\n");
      } else {
        PrintF("Unknown command: %s\n", cmd);
      }
    }
  }

  // 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
}


static bool ICacheMatch(void* one, void* two) {
  DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
  DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
  return one == two;
}


static uint32_t ICacheHash(void* key) {
  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
}


static bool AllOnOnePage(uintptr_t start, int size) {
  intptr_t start_page = (start & ~CachePage::kPageMask);
  intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
  return start_page == end_page;
}


void Simulator::set_last_debugger_input(char* input) {
  DeleteArray(last_debugger_input_);
  last_debugger_input_ = input;
}


void Simulator::FlushICache(v8::internal::HashMap* i_cache,
                            void* start_addr,
                            size_t size) {
  int64_t start = reinterpret_cast<int64_t>(start_addr);
  int64_t intra_line = (start & CachePage::kLineMask);
  start -= intra_line;
  size += intra_line;
  size = ((size - 1) | CachePage::kLineMask) + 1;
  int offset = (start & CachePage::kPageMask);
  while (!AllOnOnePage(start, size - 1)) {
    int bytes_to_flush = CachePage::kPageSize - offset;
    FlushOnePage(i_cache, start, bytes_to_flush);
    start += bytes_to_flush;
    size -= bytes_to_flush;
    DCHECK_EQ((uint64_t)0, start & CachePage::kPageMask);
    offset = 0;
  }
  if (size != 0) {
    FlushOnePage(i_cache, start, size);
  }
}


CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
  v8::internal::HashMap::Entry* entry = i_cache->Lookup(page,
                                                        ICacheHash(page),
                                                        true);
  if (entry->value == NULL) {
    CachePage* new_page = new CachePage();
    entry->value = new_page;
  }
  return reinterpret_cast<CachePage*>(entry->value);
}


// Flush from start up to and not including start + size.
void Simulator::FlushOnePage(v8::internal::HashMap* i_cache,
                             intptr_t start,
                             int size) {
  DCHECK(size <= CachePage::kPageSize);
  DCHECK(AllOnOnePage(start, size - 1));
  DCHECK((start & CachePage::kLineMask) == 0);
  DCHECK((size & CachePage::kLineMask) == 0);
  void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
  int offset = (start & CachePage::kPageMask);
  CachePage* cache_page = GetCachePage(i_cache, page);
  char* valid_bytemap = cache_page->ValidityByte(offset);
  memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
}


void Simulator::CheckICache(v8::internal::HashMap* i_cache,
                            Instruction* instr) {
  int64_t address = reinterpret_cast<int64_t>(instr);
  void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
  void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
  int offset = (address & CachePage::kPageMask);
  CachePage* cache_page = GetCachePage(i_cache, page);
  char* cache_valid_byte = cache_page->ValidityByte(offset);
  bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
  char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
  if (cache_hit) {
    // Check that the data in memory matches the contents of the I-cache.
    CHECK_EQ(0, memcmp(reinterpret_cast<void*>(instr),
                       cache_page->CachedData(offset),
                       Instruction::kInstrSize));
  } else {
    // Cache miss.  Load memory into the cache.
    memcpy(cached_line, line, CachePage::kLineLength);
    *cache_valid_byte = CachePage::LINE_VALID;
  }
}


void Simulator::Initialize(Isolate* isolate) {
  if (isolate->simulator_initialized()) return;
  isolate->set_simulator_initialized(true);
  ::v8::internal::ExternalReference::set_redirector(isolate,
                                                    &RedirectExternalReference);
}


Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
  i_cache_ = isolate_->simulator_i_cache();
  if (i_cache_ == NULL) {
    i_cache_ = new v8::internal::HashMap(&ICacheMatch);
    isolate_->set_simulator_i_cache(i_cache_);
  }
  Initialize(isolate);
  // Set up simulator support first. Some of this information is needed to
  // setup the architecture state.
  stack_size_ = FLAG_sim_stack_size * KB;
  stack_ = reinterpret_cast<char*>(malloc(stack_size_));
  pc_modified_ = false;
  icount_ = 0;
  break_count_ = 0;
  break_pc_ = NULL;
  break_instr_ = 0;

  // Set up architecture state.
  // All registers are initialized to zero to start with.
  for (int i = 0; i < kNumSimuRegisters; i++) {
    registers_[i] = 0;
  }
  for (int i = 0; i < kNumFPURegisters; i++) {
    FPUregisters_[i] = 0;
  }
  FCSR_ = 0;

  // The sp is initialized to point to the bottom (high address) of the
  // allocated stack area. To be safe in potential stack underflows we leave
  // some buffer below.
  registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64;
  // The ra 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] = bad_ra;
  registers_[ra] = bad_ra;
  InitializeCoverage();
  for (int i = 0; i < kNumExceptions; i++) {
    exceptions[i] = 0;
  }

  last_debugger_input_ = NULL;
}


Simulator::~Simulator() {
}


// 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 swi (software-interrupt) instruction that is handled by
// the simulator.  We write the original destination of the jump just at a known
// offset from the swi instruction so the simulator knows what to call.
class Redirection {
 public:
  Redirection(void* external_function, ExternalReference::Type type)
      : external_function_(external_function),
        swi_instruction_(rtCallRedirInstr),
        type_(type),
        next_(NULL) {
    Isolate* isolate = Isolate::Current();
    next_ = isolate->simulator_redirection();
    Simulator::current(isolate)->
        FlushICache(isolate->simulator_i_cache(),
                    reinterpret_cast<void*>(&swi_instruction_),
                    Instruction::kInstrSize);
    isolate->set_simulator_redirection(this);
  }

  void* address_of_swi_instruction() {
    return reinterpret_cast<void*>(&swi_instruction_);
  }

  void* external_function() { return external_function_; }
  ExternalReference::Type type() { return type_; }

  static Redirection* Get(void* external_function,
                          ExternalReference::Type type) {
    Isolate* isolate = Isolate::Current();
    Redirection* current = isolate->simulator_redirection();
    for (; current != NULL; current = current->next_) {
      if (current->external_function_ == external_function) return current;
    }
    return new Redirection(external_function, type);
  }

  static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
    char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
    char* addr_of_redirection =
        addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
    return reinterpret_cast<Redirection*>(addr_of_redirection);
  }

  static void* ReverseRedirection(int64_t reg) {
    Redirection* redirection = FromSwiInstruction(
        reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
    return redirection->external_function();
  }

 private:
  void* external_function_;
  uint32_t swi_instruction_;
  ExternalReference::Type type_;
  Redirection* next_;
};


void* Simulator::RedirectExternalReference(void* external_function,
                                           ExternalReference::Type type) {
  Redirection* redirection = Redirection::Get(external_function, type);
  return redirection->address_of_swi_instruction();
}


// Get the active Simulator for the current thread.
Simulator* Simulator::current(Isolate* isolate) {
  v8::internal::Isolate::PerIsolateThreadData* isolate_data =
       isolate->FindOrAllocatePerThreadDataForThisThread();
  DCHECK(isolate_data != NULL);
  DCHECK(isolate_data != NULL);

  Simulator* sim = isolate_data->simulator();
  if (sim == NULL) {
    // TODO(146): delete the simulator object when a thread/isolate goes away.
    sim = new Simulator(isolate);
    isolate_data->set_simulator(sim);
  }
  return sim;
}


// 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(int reg, int64_t value) {
  DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
  if (reg == pc) {
    pc_modified_ = true;
  }

  // Zero register always holds 0.
  registers_[reg] = (reg == 0) ? 0 : value;
}


void Simulator::set_dw_register(int reg, const int* dbl) {
  DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
  registers_[reg] = dbl[1];
  registers_[reg] = registers_[reg] << 32;
  registers_[reg] += dbl[0];
}


void Simulator::set_fpu_register(int fpureg, int64_t value) {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  FPUregisters_[fpureg] = value;
}


void Simulator::set_fpu_register_word(int fpureg, int32_t value) {
  // Set ONLY lower 32-bits, leaving upper bits untouched.
  // TODO(plind): big endian issue.
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  int32_t *pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]);
  *pword = value;
}


void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) {
  // Set ONLY upper 32-bits, leaving lower bits untouched.
  // TODO(plind): big endian issue.
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  int32_t *phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1;
  *phiword = value;
}


void Simulator::set_fpu_register_float(int fpureg, float value) {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  *bit_cast<float*>(&FPUregisters_[fpureg]) = value;
}


void Simulator::set_fpu_register_double(int fpureg, double value) {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  *bit_cast<double*>(&FPUregisters_[fpureg]) = value;
}


// Get the register from the architecture state. This function does handle
// the special case of accessing the PC register.
int64_t Simulator::get_register(int reg) const {
  DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
  if (reg == 0)
    return 0;
  else
    return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
}


double Simulator::get_double_from_register_pair(int reg) {
  // TODO(plind): bad ABI stuff, refactor or remove.
  DCHECK((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0));

  double dm_val = 0.0;
  // Read the bits from the unsigned integer register_[] array
  // into the double precision floating point value and return it.
  char buffer[sizeof(registers_[0])];
  memcpy(buffer, &registers_[reg], sizeof(registers_[0]));
  memcpy(&dm_val, buffer, sizeof(registers_[0]));
  return(dm_val);
}


int64_t Simulator::get_fpu_register(int fpureg) const {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  return FPUregisters_[fpureg];
}


int32_t Simulator::get_fpu_register_word(int fpureg) const {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
}


int32_t Simulator::get_fpu_register_signed_word(int fpureg) const {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
}


int32_t Simulator::get_fpu_register_hi_word(int fpureg) const {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff);
}


float Simulator::get_fpu_register_float(int fpureg) const {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg]));
}


double Simulator::get_fpu_register_double(int fpureg) const {
  DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
  return *bit_cast<double*>(&FPUregisters_[fpureg]);
}


// Runtime FP routines take up to two double arguments and zero
// or one integer arguments. All are constructed here,
// from a0-a3 or f12 and f13 (n64), or f14 (O32).
void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
  if (!IsMipsSoftFloatABI) {
    const int fparg2 = (kMipsAbi == kN64) ? 13 : 14;
    *x = get_fpu_register_double(12);
    *y = get_fpu_register_double(fparg2);
    *z = get_register(a2);
  } else {
  // TODO(plind): bad ABI stuff, refactor or remove.
    // We use a char buffer to get around the strict-aliasing rules which
    // otherwise allow the compiler to optimize away the copy.
    char buffer[sizeof(*x)];
    int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);

    // Registers a0 and a1 -> x.
    reg_buffer[0] = get_register(a0);
    reg_buffer[1] = get_register(a1);
    memcpy(x, buffer, sizeof(buffer));
    // Registers a2 and a3 -> y.
    reg_buffer[0] = get_register(a2);
    reg_buffer[1] = get_register(a3);
    memcpy(y, buffer, sizeof(buffer));
    // Register 2 -> z.
    reg_buffer[0] = get_register(a2);
    memcpy(z, buffer, sizeof(*z));
  }
}


// The return value is either in v0/v1 or f0.
void Simulator::SetFpResult(const double& result) {
  if (!IsMipsSoftFloatABI) {
    set_fpu_register_double(0, result);
  } else {
    char buffer[2 * sizeof(registers_[0])];
    int64_t* reg_buffer = reinterpret_cast<int64_t*>(buffer);
    memcpy(buffer, &result, sizeof(buffer));
    // Copy result to v0 and v1.
    set_register(v0, reg_buffer[0]);
    set_register(v1, reg_buffer[1]);
  }
}


// Helper functions for setting and testing the FCSR register's bits.
void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
  if (value) {
    FCSR_ |= (1 << cc);
  } else {
    FCSR_ &= ~(1 << cc);
  }
}


bool Simulator::test_fcsr_bit(uint32_t cc) {
  return FCSR_ & (1 << cc);
}


// Sets the rounding error codes in FCSR based on the result of the rounding.
// Returns true if the operation was invalid.
bool Simulator::set_fcsr_round_error(double original, double rounded) {
  bool ret = false;
  double max_int32 = std::numeric_limits<int32_t>::max();
  double min_int32 = std::numeric_limits<int32_t>::min();

  if (!std::isfinite(original) || !std::isfinite(rounded)) {
    set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
    ret = true;
  }

  if (original != rounded) {
    set_fcsr_bit(kFCSRInexactFlagBit, true);
  }

  if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
    set_fcsr_bit(kFCSRUnderflowFlagBit, true);
    ret = true;
  }

  if (rounded > max_int32 || rounded < min_int32) {
    set_fcsr_bit(kFCSROverflowFlagBit, true);
    // The reference is not really clear but it seems this is required:
    set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
    ret = true;
  }

  return ret;
}


// Sets the rounding error codes in FCSR based on the result of the rounding.
// Returns true if the operation was invalid.
bool Simulator::set_fcsr_round64_error(double original, double rounded) {
  bool ret = false;
  double max_int64 = std::numeric_limits<int64_t>::max();
  double min_int64 = std::numeric_limits<int64_t>::min();

  if (!std::isfinite(original) || !std::isfinite(rounded)) {
    set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
    ret = true;
  }

  if (original != rounded) {
    set_fcsr_bit(kFCSRInexactFlagBit, true);
  }

  if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
    set_fcsr_bit(kFCSRUnderflowFlagBit, true);
    ret = true;
  }

  if (rounded > max_int64 || rounded < min_int64) {
    set_fcsr_bit(kFCSROverflowFlagBit, true);
    // The reference is not really clear but it seems this is required:
    set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
    ret = true;
  }

  return ret;
}


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


bool Simulator::has_bad_pc() const {
  return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc));
}


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


// The MIPS cannot do unaligned reads and writes.  On some MIPS platforms an
// interrupt is caused.  On others it does a funky rotation thing.  For now we
// simply disallow unaligned reads, but at some point we may want to move to
// emulating the rotate behaviour.  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 not
// get the correct MIPS-like behaviour on unaligned accesses.

// TODO(plind): refactor this messy debug code when we do unaligned access.
void Simulator::DieOrDebug() {
  if (1) {  // Flag for this was removed.
    MipsDebugger dbg(this);
    dbg.Debug();
  } else {
    base::OS::Abort();
  }
}


void Simulator::TraceRegWr(int64_t value) {
  if (::v8::internal::FLAG_trace_sim) {
    SNPrintF(trace_buf_, "%016lx", value);
  }
}


// TODO(plind): consider making icount_ printing a flag option.
void Simulator::TraceMemRd(int64_t addr, int64_t value) {
  if (::v8::internal::FLAG_trace_sim) {
    SNPrintF(trace_buf_, "%016lx <-- [%016lx]    (%ld)",
             value, addr, icount_);
  }
}


void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) {
  if (::v8::internal::FLAG_trace_sim) {
    switch (t) {
      case BYTE:
        SNPrintF(trace_buf_, "               %02x --> [%016lx]",
                 static_cast<int8_t>(value), addr);
        break;
      case HALF:
        SNPrintF(trace_buf_, "            %04x --> [%016lx]",
                 static_cast<int16_t>(value), addr);
        break;
      case WORD:
        SNPrintF(trace_buf_, "        %08x --> [%016lx]",
                 static_cast<int32_t>(value), addr);
        break;
      case DWORD:
        SNPrintF(trace_buf_, "%016lx --> [%016lx]    (%ld)",
                 value, addr, icount_);
        break;
    }
  }
}


// TODO(plind): sign-extend and zero-extend not implmented properly
// on all the ReadXX functions, I don't think re-interpret cast does it.
int32_t Simulator::ReadW(int64_t addr, Instruction* instr) {
  if (addr >=0 && addr < 0x400) {
    // This has to be a NULL-dereference, drop into debugger.
    PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n",
           addr, reinterpret_cast<intptr_t>(instr));
    DieOrDebug();
  }
  if ((addr & 0x3) == 0) {
    int32_t* ptr = reinterpret_cast<int32_t*>(addr);
    TraceMemRd(addr, static_cast<int64_t>(*ptr));
    return *ptr;
  }
  PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
  return 0;
}


uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) {
  if (addr >=0 && addr < 0x400) {
    // This has to be a NULL-dereference, drop into debugger.
    PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n",
           addr, reinterpret_cast<intptr_t>(instr));
    DieOrDebug();
  }
  if ((addr & 0x3) == 0) {
    uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
    TraceMemRd(addr, static_cast<int64_t>(*ptr));
    return *ptr;
  }
  PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
  return 0;
}


void Simulator::WriteW(int64_t addr, int value, Instruction* instr) {
  if (addr >= 0 && addr < 0x400) {
    // This has to be a NULL-dereference, drop into debugger.
    PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n",
           addr, reinterpret_cast<intptr_t>(instr));
    DieOrDebug();
  }
  if ((addr & 0x3) == 0) {
    TraceMemWr(addr, value, WORD);
    int* ptr = reinterpret_cast<int*>(addr);
    *ptr = value;
    return;
  }
  PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
}


int64_t Simulator::Read2W(int64_t addr, Instruction* instr) {
  if (addr >=0 && addr < 0x400) {
    // This has to be a NULL-dereference, drop into debugger.
    PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n",
           addr, reinterpret_cast<intptr_t>(instr));
    DieOrDebug();
  }
  if ((addr & kPointerAlignmentMask) == 0) {
    int64_t* ptr = reinterpret_cast<int64_t*>(addr);
    TraceMemRd(addr, *ptr);
    return *ptr;
  }
  PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
  return 0;
}


void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) {
  if (addr >= 0 && addr < 0x400) {
    // This has to be a NULL-dereference, drop into debugger.
    PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n",
           addr, reinterpret_cast<intptr_t>(instr));
    DieOrDebug();
  }
  if ((addr & kPointerAlignmentMask) == 0) {
    TraceMemWr(addr, value, DWORD);
    int64_t* ptr = reinterpret_cast<int64_t*>(addr);
    *ptr = value;
    return;
  }
  PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
}


double Simulator::ReadD(int64_t addr, Instruction* instr) {
  if ((addr & kDoubleAlignmentMask) == 0) {
    double* ptr = reinterpret_cast<double*>(addr);
    return *ptr;
  }
  PrintF("Unaligned (double) read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  base::OS::Abort();
  return 0;
}


void Simulator::WriteD(int64_t addr, double value, Instruction* instr) {
  if ((addr & kDoubleAlignmentMask) == 0) {
    double* ptr = reinterpret_cast<double*>(addr);
    *ptr = value;
    return;
  }
  PrintF("Unaligned (double) write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
}


uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) {
  if ((addr & 1) == 0) {
    uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
    TraceMemRd(addr, static_cast<int64_t>(*ptr));
    return *ptr;
  }
  PrintF("Unaligned unsigned halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
  return 0;
}


int16_t Simulator::ReadH(int64_t addr, Instruction* instr) {
  if ((addr & 1) == 0) {
    int16_t* ptr = reinterpret_cast<int16_t*>(addr);
    TraceMemRd(addr, static_cast<int64_t>(*ptr));
    return *ptr;
  }
  PrintF("Unaligned signed halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
  return 0;
}


void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) {
  if ((addr & 1) == 0) {
    TraceMemWr(addr, value, HALF);
    uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
    *ptr = value;
    return;
  }
  PrintF(
      "Unaligned unsigned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
      addr,
      reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
}


void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) {
  if ((addr & 1) == 0) {
    TraceMemWr(addr, value, HALF);
    int16_t* ptr = reinterpret_cast<int16_t*>(addr);
    *ptr = value;
    return;
  }
  PrintF("Unaligned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n",
         addr,
         reinterpret_cast<intptr_t>(instr));
  DieOrDebug();
}


uint32_t Simulator::ReadBU(int64_t addr) {
  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
  TraceMemRd(addr, static_cast<int64_t>(*ptr));
  return *ptr & 0xff;
}


int32_t Simulator::ReadB(int64_t addr) {
  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
  TraceMemRd(addr, static_cast<int64_t>(*ptr));
  return *ptr;
}


void Simulator::WriteB(int64_t addr, uint8_t value) {
  TraceMemWr(addr, value, BYTE);
  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
  *ptr = value;
}


void Simulator::WriteB(int64_t addr, int8_t value) {
  TraceMemWr(addr, value, BYTE);
  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
  *ptr = value;
}


// Returns the limit of the stack area to enable checking for stack overflows.
uintptr_t Simulator::StackLimit() const {
  // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
  // pushing values.
  return reinterpret_cast<uintptr_t>(stack_) + 1024;
}


// Unsupported instructions use Format to print an error and stop execution.
void Simulator::Format(Instruction* instr, const char* format) {
  PrintF("Simulator found unsupported instruction:\n 0x%08lx: %s\n",
         reinterpret_cast<intptr_t>(instr), format);
  UNIMPLEMENTED_MIPS();
}


// Calls into the V8 runtime are based on this very simple interface.
// Note: To be able to return two values from some calls the code in runtime.cc
// uses the ObjectPair which is essentially two 32-bit values stuffed into a
// 64-bit value. With the code below we assume that all runtime calls return
// 64 bits of result. If they don't, the v1 result register contains a bogus
// value, which is fine because it is caller-saved.

struct ObjectPair {
  Object* x;
  Object* y;
};

typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
                                        int64_t arg1,
                                        int64_t arg2,
                                        int64_t arg3,
                                        int64_t arg4,
                                        int64_t arg5);


// These prototypes handle the four types of FP calls.
typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
typedef double (*SimulatorRuntimeFPCall)(double darg0);
typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);

// This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h).
typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);

// This signature supports direct call to accessor getter callback.
typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
typedef void (*SimulatorRuntimeProfilingGetterCall)(
    int64_t arg0, int64_t arg1, void* arg2);

// Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime. They are also used for debugging with simulator.
void Simulator::SoftwareInterrupt(Instruction* instr) {
  // There are several instructions that could get us here,
  // the break_ instruction, or several variants of traps. All
  // Are "SPECIAL" class opcode, and are distinuished by function.
  int32_t func = instr->FunctionFieldRaw();
  uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;
  // We first check if we met a call_rt_redirected.
  if (instr->InstructionBits() == rtCallRedirInstr) {
    Redirection* redirection = Redirection::FromSwiInstruction(instr);
    int64_t arg0 = get_register(a0);
    int64_t arg1 = get_register(a1);
    int64_t arg2 = get_register(a2);
    int64_t arg3 = get_register(a3);
    int64_t arg4, arg5;

    if (kMipsAbi == kN64) {
      arg4 = get_register(a4);  // Abi n64 register a4.
      arg5 = get_register(a5);  // Abi n64 register a5.
    } else {  // Abi O32.
      int64_t* stack_pointer = reinterpret_cast<int64_t*>(get_register(sp));
      // Args 4 and 5 are on the stack after the reserved space for args 0..3.
      arg4 = stack_pointer[4];
      arg5 = stack_pointer[5];
    }
    bool fp_call =
         (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
         (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
         (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
         (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);

    if (!IsMipsSoftFloatABI) {
      // With the hard floating point calling convention, double
      // arguments are passed in FPU registers. Fetch the arguments
      // from there and call the builtin using soft floating point
      // convention.
      switch (redirection->type()) {
      case ExternalReference::BUILTIN_FP_FP_CALL:
      case ExternalReference::BUILTIN_COMPARE_CALL:
        arg0 = get_fpu_register(f12);
        arg1 = get_fpu_register(f13);
        arg2 = get_fpu_register(f14);
        arg3 = get_fpu_register(f15);
        break;
      case ExternalReference::BUILTIN_FP_CALL:
        arg0 = get_fpu_register(f12);
        arg1 = get_fpu_register(f13);
        break;
      case ExternalReference::BUILTIN_FP_INT_CALL:
        arg0 = get_fpu_register(f12);
        arg1 = get_fpu_register(f13);
        arg2 = get_register(a2);
        break;
      default:
        break;
      }
    }

    // This is dodgy but it works because the C entry stubs are never moved.
    // See comment in codegen-arm.cc and bug 1242173.
    int64_t saved_ra = get_register(ra);

    intptr_t external =
          reinterpret_cast<intptr_t>(redirection->external_function());

    // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
    // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
    // simulator. Soft-float has additional abstraction of ExternalReference,
    // to support serialization.
    if (fp_call) {
      double dval0, dval1;  // one or two double parameters
      int32_t ival;         // zero or one integer parameters
      int64_t iresult = 0;  // integer return value
      double dresult = 0;   // double return value
      GetFpArgs(&dval0, &dval1, &ival);
      SimulatorRuntimeCall generic_target =
          reinterpret_cast<SimulatorRuntimeCall>(external);
      if (::v8::internal::FLAG_trace_sim) {
        switch (redirection->type()) {
          case ExternalReference::BUILTIN_FP_FP_CALL:
          case ExternalReference::BUILTIN_COMPARE_CALL:
            PrintF("Call to host function at %p with args %f, %f",
                   FUNCTION_ADDR(generic_target), dval0, dval1);
            break;
          case ExternalReference::BUILTIN_FP_CALL:
            PrintF("Call to host function at %p with arg %f",
                FUNCTION_ADDR(generic_target), dval0);
            break;
          case ExternalReference::BUILTIN_FP_INT_CALL:
            PrintF("Call to host function at %p with args %f, %d",
                   FUNCTION_ADDR(generic_target), dval0, ival);
            break;
          default:
            UNREACHABLE();
            break;
        }
      }
      switch (redirection->type()) {
      case ExternalReference::BUILTIN_COMPARE_CALL: {
        SimulatorRuntimeCompareCall target =
          reinterpret_cast<SimulatorRuntimeCompareCall>(external);
        iresult = target(dval0, dval1);
        set_register(v0, static_cast<int64_t>(iresult));
      //  set_register(v1, static_cast<int64_t>(iresult >> 32));
        break;
      }
      case ExternalReference::BUILTIN_FP_FP_CALL: {
        SimulatorRuntimeFPFPCall target =
          reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
        dresult = target(dval0, dval1);
        SetFpResult(dresult);
        break;
      }
      case ExternalReference::BUILTIN_FP_CALL: {
        SimulatorRuntimeFPCall target =
          reinterpret_cast<SimulatorRuntimeFPCall>(external);
        dresult = target(dval0);
        SetFpResult(dresult);
        break;
      }
      case ExternalReference::BUILTIN_FP_INT_CALL: {
        SimulatorRuntimeFPIntCall target =
          reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
        dresult = target(dval0, ival);
        SetFpResult(dresult);
        break;
      }
      default:
        UNREACHABLE();
        break;
      }
      if (::v8::internal::FLAG_trace_sim) {
        switch (redirection->type()) {
        case ExternalReference::BUILTIN_COMPARE_CALL:
          PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
          break;
        case ExternalReference::BUILTIN_FP_FP_CALL:
        case ExternalReference::BUILTIN_FP_CALL:
        case ExternalReference::BUILTIN_FP_INT_CALL:
          PrintF("Returned %f\n", dresult);
          break;
        default:
          UNREACHABLE();
          break;
        }
      }
    } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
      if (::v8::internal::FLAG_trace_sim) {
        PrintF("Call to host function at %p args %08lx\n",
            reinterpret_cast<void*>(external), arg0);
      }
      SimulatorRuntimeDirectApiCall target =
          reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
      target(arg0);
    } else if (
        redirection->type() == ExternalReference::PROFILING_API_CALL) {
      if (::v8::internal::FLAG_trace_sim) {
        PrintF("Call to host function at %p args %08lx %08lx\n",
            reinterpret_cast<void*>(external), arg0, arg1);
      }
      SimulatorRuntimeProfilingApiCall target =
          reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
      target(arg0, Redirection::ReverseRedirection(arg1));
    } else if (
        redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
      if (::v8::internal::FLAG_trace_sim) {
        PrintF("Call to host function at %p args %08lx %08lx\n",
            reinterpret_cast<void*>(external), arg0, arg1);
      }
      SimulatorRuntimeDirectGetterCall target =
          reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
      target(arg0, arg1);
    } else if (
        redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
      if (::v8::internal::FLAG_trace_sim) {
        PrintF("Call to host function at %p args %08lx %08lx %08lx\n",
            reinterpret_cast<void*>(external), arg0, arg1, arg2);
      }
      SimulatorRuntimeProfilingGetterCall target =
          reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
      target(arg0, arg1, Redirection::ReverseRedirection(arg2));
    } else {
      SimulatorRuntimeCall target =
                  reinterpret_cast<SimulatorRuntimeCall>(external);
      if (::v8::internal::FLAG_trace_sim) {
        PrintF(
            "Call to host function at %p "
            "args %08lx, %08lx, %08lx, %08lx, %08lx, %08lx\n",
            FUNCTION_ADDR(target),
            arg0,
            arg1,
            arg2,
            arg3,
            arg4,
            arg5);
      }
      // int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
      // set_register(v0, static_cast<int32_t>(result));
      // set_register(v1, static_cast<int32_t>(result >> 32));
      ObjectPair result = target(arg0, arg1, arg2, arg3, arg4, arg5);
      set_register(v0, (int64_t)(result.x));
      set_register(v1, (int64_t)(result.y));
    }
     if (::v8::internal::FLAG_trace_sim) {
      PrintF("Returned %08lx : %08lx\n", get_register(v1), get_register(v0));
    }
    set_register(ra, saved_ra);
    set_pc(get_register(ra));

  } else if (func == BREAK && code <= kMaxStopCode) {
    if (IsWatchpoint(code)) {
      PrintWatchpoint(code);
    } else {
      IncreaseStopCounter(code);
      HandleStop(code, instr);
    }
  } else {
    // All remaining break_ codes, and all traps are handled here.
    MipsDebugger dbg(this);
    dbg.Debug();
  }
}


// Stop helper functions.
bool Simulator::IsWatchpoint(uint64_t code) {
  return (code <= kMaxWatchpointCode);
}


void Simulator::PrintWatchpoint(uint64_t code) {
  MipsDebugger dbg(this);
  ++break_count_;
  PrintF("\n---- break %ld marker: %3d  (instr count: %8ld) ----------"
         "----------------------------------",
         code, break_count_, icount_);
  dbg.PrintAllRegs();  // Print registers and continue running.
}


void Simulator::HandleStop(uint64_t code, Instruction* instr) {
  // Stop if it is enabled, otherwise go on jumping over the stop
  // and the message address.
  if (IsEnabledStop(code)) {
    MipsDebugger dbg(this);
    dbg.Stop(instr);
  } else {
    set_pc(get_pc() + 2 * Instruction::kInstrSize);
  }
}


bool Simulator::IsStopInstruction(Instruction* instr) {
  int32_t func = instr->FunctionFieldRaw();
  uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
  return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
}


bool Simulator::IsEnabledStop(uint64_t code) {
  DCHECK(code <= kMaxStopCode);
  DCHECK(code > kMaxWatchpointCode);
  return !(watched_stops_[code].count & kStopDisabledBit);
}


void Simulator::EnableStop(uint64_t code) {
  if (!IsEnabledStop(code)) {
    watched_stops_[code].count &= ~kStopDisabledBit;
  }
}


void Simulator::DisableStop(uint64_t code) {
  if (IsEnabledStop(code)) {
    watched_stops_[code].count |= kStopDisabledBit;
  }
}


void Simulator::IncreaseStopCounter(uint64_t code) {
  DCHECK(code <= kMaxStopCode);
  if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
    PrintF("Stop counter for code %ld has overflowed.\n"
           "Enabling this code and reseting the counter to 0.\n", code);
    watched_stops_[code].count = 0;
    EnableStop(code);
  } else {
    watched_stops_[code].count++;
  }
}


// Print a stop status.
void Simulator::PrintStopInfo(uint64_t code) {
  if (code <= kMaxWatchpointCode) {
    PrintF("That is a watchpoint, not a stop.\n");
    return;
  } else if (code > kMaxStopCode) {
    PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
    return;
  }
  const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled";
  int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
  // Don't print the state of unused breakpoints.
  if (count != 0) {
    if (watched_stops_[code].desc) {
      PrintF("stop %ld - 0x%lx: \t%s, \tcounter = %i, \t%s\n",
             code, code, state, count, watched_stops_[code].desc);
    } else {
      PrintF("stop %ld - 0x%lx: \t%s, \tcounter = %i\n",
             code, code, state, count);
    }
  }
}


void Simulator::SignalExceptions() {
  for (int i = 1; i < kNumExceptions; i++) {
    if (exceptions[i] != 0) {
      V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i);
    }
  }
}


// Handle execution based on instruction types.

void Simulator::ConfigureTypeRegister(Instruction* instr,
                                      int64_t* alu_out,
                                      int64_t* i64hilo,
                                      uint64_t* u64hilo,
                                      int64_t* next_pc,
                                      int64_t* return_addr_reg,
                                      bool* do_interrupt,
                                      int64_t* i128resultH,
                                      int64_t* i128resultL) {
  // Every local variable declared here needs to be const.
  // This is to make sure that changed values are sent back to
  // DecodeTypeRegister correctly.

  // Instruction fields.
  const Opcode   op     = instr->OpcodeFieldRaw();
  const int64_t  rs_reg = instr->RsValue();
  const int64_t  rs     = get_register(rs_reg);
  const uint64_t rs_u   = static_cast<uint64_t>(rs);
  const int64_t  rt_reg = instr->RtValue();
  const int64_t  rt     = get_register(rt_reg);
  const uint64_t rt_u   = static_cast<uint64_t>(rt);
  const int64_t  rd_reg = instr->RdValue();
  const uint64_t sa     = instr->SaValue();

  const int32_t  fs_reg = instr->FsValue();


  // ---------- Configuration.
  switch (op) {
    case COP1:    // Coprocessor instructions.
      switch (instr->RsFieldRaw()) {
        case CFC1:
          // At the moment only FCSR is supported.
          DCHECK(fs_reg == kFCSRRegister);
          *alu_out = FCSR_;
          break;
        case MFC1:
          *alu_out = static_cast<int64_t>(get_fpu_register_word(fs_reg));
          break;
        case DMFC1:
          *alu_out = get_fpu_register(fs_reg);
          break;
        case MFHC1:
          *alu_out = get_fpu_register_hi_word(fs_reg);
          break;
        case CTC1:
        case MTC1:
        case DMTC1:
        case MTHC1:
        case S:
        case D:
        case W:
        case L:
        case PS:
          // Do everything in the execution step.
          break;
        default:
        // BC1 BC1EQZ BC1NEZ handled in DecodeTypeImmed, should never come here.
           UNREACHABLE();
      }
      break;
    case COP1X:
      break;
    case SPECIAL:
      switch (instr->FunctionFieldRaw()) {
        case JR:
        case JALR:
          *next_pc = get_register(instr->RsValue());
          *return_addr_reg = instr->RdValue();
          break;
        case SLL:
          *alu_out = (int32_t)rt << sa;
          break;
        case DSLL:
          *alu_out = rt << sa;
          break;
        case DSLL32:
          *alu_out = rt << sa << 32;
          break;
        case SRL:
          if (rs_reg == 0) {
            // Regular logical right shift of a word by a fixed number of
            // bits instruction. RS field is always equal to 0.
            *alu_out = (uint32_t)rt_u >> sa;
          } else {
            // Logical right-rotate of a word by a fixed number of bits. This
            // is special case of SRL instruction, added in MIPS32 Release 2.
            // RS field is equal to 00001.
            *alu_out = ((uint32_t)rt_u >> sa) | ((uint32_t)rt_u << (32 - sa));
          }
          break;
        case DSRL:
          *alu_out = rt_u >> sa;
          break;
        case DSRL32:
          *alu_out = rt_u >> sa >> 32;
          break;
        case SRA:
          *alu_out = (int32_t)rt >> sa;
          break;
        case DSRA:
          *alu_out = rt >> sa;
          break;
        case DSRA32:
          *alu_out = rt >> sa >> 32;
          break;
        case SLLV:
          *alu_out = (int32_t)rt << rs;
          break;
        case DSLLV:
          *alu_out = rt << rs;
          break;
        case SRLV:
          if (sa == 0) {
            // Regular logical right-shift of a word by a variable number of
            // bits instruction. SA field is always equal to 0.
            *alu_out = (uint32_t)rt_u >> rs;
          } else {
            // Logical right-rotate of a word by a variable number of bits.
            // This is special case od SRLV instruction, added in MIPS32
            // Release 2. SA field is equal to 00001.
            *alu_out =
                ((uint32_t)rt_u >> rs_u) | ((uint32_t)rt_u << (32 - rs_u));
          }
          break;
        case DSRLV:
          if (sa == 0) {
            // Regular logical right-shift of a word by a variable number of
            // bits instruction. SA field is always equal to 0.
            *alu_out = rt_u >> rs;
          } else {
            // Logical right-rotate of a word by a variable number of bits.
            // This is special case od SRLV instruction, added in MIPS32
            // Release 2. SA field is equal to 00001.
            *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u));
          }
          break;
        case SRAV:
          *alu_out = (int32_t)rt >> rs;
          break;
        case DSRAV:
          *alu_out = rt >> rs;
          break;
        case MFHI:  // MFHI == CLZ on R6.
          if (kArchVariant != kMips64r6) {
            DCHECK(instr->SaValue() == 0);
            *alu_out = get_register(HI);
          } else {
            // MIPS spec: If no bits were set in GPR rs, the result written to
            // GPR rd is 32.
            DCHECK(instr->SaValue() == 1);
            *alu_out = base::bits::CountLeadingZeros32(rs_u);
          }
          break;
        case MFLO:
          *alu_out = get_register(LO);
          break;
        case MULT:  // MULT == D_MUL_MUH.
          // TODO(plind) - Unify MULT/DMULT with single set of 64-bit HI/Lo
          // regs.
          // TODO(plind) - make the 32-bit MULT ops conform to spec regarding
          //   checking of 32-bit input values, and un-define operations of HW.
          *i64hilo = rs * rt;
          break;
        case MULTU:
          *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u);
          break;
        case DMULT:  // DMULT == D_MUL_MUH.
          if (kArchVariant != kMips64r6) {
            *i128resultH = MultiplyHighSigned(rs, rt);
            *i128resultL = rs * rt;
          } else {
            switch (instr->SaValue()) {
              case MUL_OP:
                *i128resultL = rs * rt;
                break;
              case MUH_OP:
                *i128resultH = MultiplyHighSigned(rs, rt);
                break;
              default:
                UNIMPLEMENTED_MIPS();
                break;
            }
          }
          break;
        case DMULTU:
          UNIMPLEMENTED_MIPS();
          break;
        case ADD:
        case DADD:
          if (HaveSameSign(rs, rt)) {
            if (rs > 0) {
              exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
            } else if (rs < 0) {
              exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
            }
          }
          *alu_out = rs + rt;
          break;
        case ADDU: {
            int32_t alu32_out = rs + rt;
            // Sign-extend result of 32bit operation into 64bit register.
            *alu_out = static_cast<int64_t>(alu32_out);
          }
          break;
        case DADDU:
          *alu_out = rs + rt;
          break;
        case SUB:
        case DSUB:
          if (!HaveSameSign(rs, rt)) {
            if (rs > 0) {
              exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt);
            } else if (rs < 0) {
              exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt);
            }
          }
          *alu_out = rs - rt;
          break;
        case SUBU: {
            int32_t alu32_out = rs - rt;
            // Sign-extend result of 32bit operation into 64bit register.
            *alu_out = static_cast<int64_t>(alu32_out);
          }
          break;
        case DSUBU:
          *alu_out = rs - rt;
          break;
        case AND:
          *alu_out = rs & rt;
          break;
        case OR:
          *alu_out = rs | rt;
          break;
        case XOR:
          *alu_out = rs ^ rt;
          break;
        case NOR:
          *alu_out = ~(rs | rt);
          break;
        case SLT:
          *alu_out = rs < rt ? 1 : 0;
          break;
        case SLTU:
          *alu_out = rs_u < rt_u ? 1 : 0;
          break;
        // Break and trap instructions.
        case BREAK:

          *do_interrupt = true;
          break;
        case TGE:
          *do_interrupt = rs >= rt;
          break;
        case TGEU:
          *do_interrupt = rs_u >= rt_u;
          break;
        case TLT:
          *do_interrupt = rs < rt;
          break;
        case TLTU:
          *do_interrupt = rs_u < rt_u;
          break;
        case TEQ:
          *do_interrupt = rs == rt;
          break;
        case TNE:
          *do_interrupt = rs != rt;
          break;
        case MOVN:
        case MOVZ:
        case MOVCI:
          // No action taken on decode.
          break;
        case DIV:
        case DIVU:
        case DDIV:
        case DDIVU:
          // div and divu never raise exceptions.
          break;
        default:
          UNREACHABLE();
      }
      break;
    case SPECIAL2:
      switch (instr->FunctionFieldRaw()) {
        case MUL:
          // Only the lower 32 bits are kept.
          *alu_out = (int32_t)rs_u * (int32_t)rt_u;
          break;
        case CLZ:
          // MIPS32 spec: If no bits were set in GPR rs, the result written to
          // GPR rd is 32.
          *alu_out = base::bits::CountLeadingZeros32(rs_u);
          break;
        default:
          UNREACHABLE();
      }
      break;
    case SPECIAL3:
      switch (instr->FunctionFieldRaw()) {
        case INS: {   // Mips32r2 instruction.
          // Interpret rd field as 5-bit msb of insert.
          uint16_t msb = rd_reg;
          // Interpret sa field as 5-bit lsb of insert.
          uint16_t lsb = sa;
          uint16_t size = msb - lsb + 1;
          uint32_t mask = (1 << size) - 1;
          *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
          break;
        }
        case EXT: {   // Mips32r2 instruction.
          // Interpret rd field as 5-bit msb of extract.
          uint16_t msb = rd_reg;
          // Interpret sa field as 5-bit lsb of extract.
          uint16_t lsb = sa;
          uint16_t size = msb + 1;
          uint32_t mask = (1 << size) - 1;
          *alu_out = (rs_u & (mask << lsb)) >> lsb;
          break;
        }
        default:
          UNREACHABLE();
      }
      break;
    default:
      UNREACHABLE();
  }
}


void Simulator::DecodeTypeRegister(Instruction* instr) {
  // Instruction fields.
  const Opcode   op     = instr->OpcodeFieldRaw();
  const int64_t  rs_reg = instr->RsValue();
  const int64_t  rs     = get_register(rs_reg);
  const uint64_t rs_u   = static_cast<uint32_t>(rs);
  const int64_t  rt_reg = instr->RtValue();
  const int64_t  rt     = get_register(rt_reg);
  const uint64_t rt_u   = static_cast<uint32_t>(rt);
  const int64_t  rd_reg = instr->RdValue();

  const int32_t  fr_reg = instr->FrValue();
  const int32_t  fs_reg = instr->FsValue();
  const int32_t  ft_reg = instr->FtValue();
  const int64_t  fd_reg = instr->FdValue();
  int64_t  i64hilo = 0;
  uint64_t u64hilo = 0;

  // ALU output.
  // It should not be used as is. Instructions using it should always
  // initialize it first.
  int64_t alu_out = 0x12345678;

  // For break and trap instructions.
  bool do_interrupt = false;

  // For jr and jalr.
  // Get current pc.
  int64_t current_pc = get_pc();
  // Next pc
  int64_t next_pc = 0;
  int64_t return_addr_reg = 31;

  int64_t i128resultH;
  int64_t i128resultL;

  // Set up the variables if needed before executing the instruction.
  ConfigureTypeRegister(instr,
                        &alu_out,
                        &i64hilo,
                        &u64hilo,
                        &next_pc,
                        &return_addr_reg,
                        &do_interrupt,
                        &i128resultH,
                        &i128resultL);

  // ---------- Raise exceptions triggered.
  SignalExceptions();

  // ---------- Execution.
  switch (op) {
    case COP1:
      switch (instr->RsFieldRaw()) {
        case BC1:   // Branch on coprocessor condition.
        case BC1EQZ:
        case BC1NEZ:
          UNREACHABLE();
          break;
        case CFC1:
          set_register(rt_reg, alu_out);
          break;
        case MFC1:
        case DMFC1:
        case MFHC1:
          set_register(rt_reg, alu_out);
          break;
        case CTC1:
          // At the moment only FCSR is supported.
          DCHECK(fs_reg == kFCSRRegister);
          FCSR_ = registers_[rt_reg];
          break;
        case MTC1:
          // Hardware writes upper 32-bits to zero on mtc1.
          set_fpu_register_hi_word(fs_reg, 0);
          set_fpu_register_word(fs_reg, registers_[rt_reg]);
          break;
        case DMTC1:
          set_fpu_register(fs_reg, registers_[rt_reg]);
          break;
        case MTHC1:
          set_fpu_register_hi_word(fs_reg, registers_[rt_reg]);
          break;
        case S:
          float f;
          switch (instr->FunctionFieldRaw()) {
            case CVT_D_S:
              f = get_fpu_register_float(fs_reg);
              set_fpu_register_double(fd_reg, static_cast<double>(f));
              break;
            default:
            // CVT_W_S CVT_L_S TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
            // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
              UNREACHABLE();
          }
          break;
        case D:
          double ft, fs;
          uint32_t cc, fcsr_cc;
          int64_t  i64;
          fs = get_fpu_register_double(fs_reg);
          ft = get_fpu_register_double(ft_reg);
          cc = instr->FCccValue();
          fcsr_cc = get_fcsr_condition_bit(cc);
          switch (instr->FunctionFieldRaw()) {
            case ADD_D:
              set_fpu_register_double(fd_reg, fs + ft);
              break;
            case SUB_D:
              set_fpu_register_double(fd_reg, fs - ft);
              break;
            case MUL_D:
              set_fpu_register_double(fd_reg, fs * ft);
              break;
            case DIV_D:
              set_fpu_register_double(fd_reg, fs / ft);
              break;
            case ABS_D:
              set_fpu_register_double(fd_reg, fabs(fs));
              break;
            case MOV_D:
              set_fpu_register_double(fd_reg, fs);
              break;
            case NEG_D:
              set_fpu_register_double(fd_reg, -fs);
              break;
            case SQRT_D:
              set_fpu_register_double(fd_reg, sqrt(fs));
              break;
            case C_UN_D:
              set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
              break;
            case C_EQ_D:
              set_fcsr_bit(fcsr_cc, (fs == ft));
              break;
            case C_UEQ_D:
              set_fcsr_bit(fcsr_cc,
                           (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
              break;
            case C_OLT_D:
              set_fcsr_bit(fcsr_cc, (fs < ft));
              break;
            case C_ULT_D:
              set_fcsr_bit(fcsr_cc,
                           (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
              break;
            case C_OLE_D:
              set_fcsr_bit(fcsr_cc, (fs <= ft));
              break;
            case C_ULE_D:
              set_fcsr_bit(fcsr_cc,
                           (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
              break;
            case CVT_W_D:   // Convert double to word.
              // Rounding modes are not yet supported.
              DCHECK((FCSR_ & 3) == 0);
              // In rounding mode 0 it should behave like ROUND.
              // No break.
            case ROUND_W_D:  // Round double to word (round half to even).
              {
                double rounded = std::floor(fs + 0.5);
                int32_t result = static_cast<int32_t>(rounded);
                if ((result & 1) != 0 && result - fs == 0.5) {
                  // If the number is halfway between two integers,
                  // round to the even one.
                  result--;
                }
                set_fpu_register_word(fd_reg, result);
                if (set_fcsr_round_error(fs, rounded)) {
                  set_fpu_register(fd_reg, kFPUInvalidResult);
                }
              }
              break;
            case TRUNC_W_D:  // Truncate double to word (round towards 0).
              {
                double rounded = trunc(fs);
                int32_t result = static_cast<int32_t>(rounded);
                set_fpu_register_word(fd_reg, result);
                if (set_fcsr_round_error(fs, rounded)) {
                  set_fpu_register(fd_reg, kFPUInvalidResult);
                }
              }
              break;
            case FLOOR_W_D:  // Round double to word towards negative infinity.
              {
                double rounded = std::floor(fs);
                int32_t result = static_cast<int32_t>(rounded);
                set_fpu_register_word(fd_reg, result);
                if (set_fcsr_round_error(fs, rounded)) {
                  set_fpu_register(fd_reg, kFPUInvalidResult);
                }
              }
              break;
            case CEIL_W_D:  // Round double to word towards positive infinity.
              {
                double rounded = std::ceil(fs);
                int32_t result = static_cast<int32_t>(rounded);
                set_fpu_register_word(fd_reg, result);
                if (set_fcsr_round_error(fs, rounded)) {
                  set_fpu_register(fd_reg, kFPUInvalidResult);
                }
              }
              break;
            case CVT_S_D:  // Convert double to float (single).
              set_fpu_register_float(fd_reg, static_cast<float>(fs));
              break;
            case CVT_L_D:   // Mips64r2: Truncate double to 64-bit long-word.
              // Rounding modes are not yet supported.
              DCHECK((FCSR_ & 3) == 0);
              // In rounding mode 0 it should behave like ROUND.
              // No break.
            case ROUND_L_D: {  // Mips64r2 instruction.
              // check error cases
              double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
              int64_t result = static_cast<int64_t>(rounded);
              set_fpu_register(fd_reg, result);
              if (set_fcsr_round64_error(fs, rounded)) {
                set_fpu_register(fd_reg, kFPU64InvalidResult);
              }
              break;
            }
            case TRUNC_L_D: {  // Mips64r2 instruction.
              double rounded = trunc(fs);
              int64_t result = static_cast<int64_t>(rounded);
              set_fpu_register(fd_reg, result);
              if (set_fcsr_round64_error(fs, rounded)) {
                set_fpu_register(fd_reg, kFPU64InvalidResult);
              }
              break;
            }
            case FLOOR_L_D: {  // Mips64r2 instruction.
              double rounded = floor(fs);
              int64_t result = static_cast<int64_t>(rounded);
              set_fpu_register(fd_reg, result);
              if (set_fcsr_round64_error(fs, rounded)) {
                set_fpu_register(fd_reg, kFPU64InvalidResult);
              }
              break;
            }
            case CEIL_L_D: {  // Mips64r2 instruction.
              double rounded = ceil(fs);
              int64_t result = static_cast<int64_t>(rounded);
              set_fpu_register(fd_reg, result);
              if (set_fcsr_round64_error(fs, rounded)) {
                set_fpu_register(fd_reg, kFPU64InvalidResult);
              }
              break;
            }
            case C_F_D:
              UNIMPLEMENTED_MIPS();
              break;
            default:
              UNREACHABLE();
          }
          break;
        case W:
          switch (instr->FunctionFieldRaw()) {
            case CVT_S_W:   // Convert word to float (single).
              alu_out = get_fpu_register_signed_word(fs_reg);
              set_fpu_register_float(fd_reg, static_cast<float>(alu_out));
              break;
            case CVT_D_W:   // Convert word to double.
              alu_out = get_fpu_register_signed_word(fs_reg);
              set_fpu_register_double(fd_reg, static_cast<double>(alu_out));
              break;
            default:  // Mips64r6 CMP.S instructions unimplemented.
              UNREACHABLE();
          }
          break;
        case L:
          fs = get_fpu_register_double(fs_reg);
          ft = get_fpu_register_double(ft_reg);
          switch (instr->FunctionFieldRaw()) {
            case CVT_D_L:  // Mips32r2 instruction.
              i64 = get_fpu_register(fs_reg);
              set_fpu_register_double(fd_reg, static_cast<double>(i64));
              break;
            case CVT_S_L:
              UNIMPLEMENTED_MIPS();
              break;
            case CMP_AF:  // Mips64r6 CMP.D instructions.
              UNIMPLEMENTED_MIPS();
              break;
            case CMP_UN:
              if (std::isnan(fs) || std::isnan(ft)) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            case CMP_EQ:
              if (fs == ft) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            case CMP_UEQ:
              if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            case CMP_LT:
              if (fs < ft) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            case CMP_ULT:
              if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            case CMP_LE:
              if (fs <= ft) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            case CMP_ULE:
              if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
                set_fpu_register(fd_reg, -1);
              } else {
                set_fpu_register(fd_reg, 0);
              }
              break;
            default:  // CMP_OR CMP_UNE CMP_NE UNIMPLEMENTED
              UNREACHABLE();
          }
          break;
        default:
          UNREACHABLE();
      }
      break;
    case COP1X:
      switch (instr->FunctionFieldRaw()) {
        case MADD_D:
          double fr, ft, fs;
          fr = get_fpu_register_double(fr_reg);
          fs = get_fpu_register_double(fs_reg);
          ft = get_fpu_register_double(ft_reg);
          set_fpu_register_double(fd_reg, fs * ft + fr);
          break;
        default:
          UNREACHABLE();
      }
      break;
    case SPECIAL:
      switch (instr->FunctionFieldRaw()) {
        case JR: {
          Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
              current_pc+Instruction::kInstrSize);
          BranchDelayInstructionDecode(branch_delay_instr);
          set_pc(next_pc);
          pc_modified_ = true;
          break;
        }
        case JALR: {
          Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
              current_pc+Instruction::kInstrSize);
          BranchDelayInstructionDecode(branch_delay_instr);
          set_register(return_addr_reg,
                       current_pc + 2 * Instruction::kInstrSize);
          set_pc(next_pc);
          pc_modified_ = true;
          break;
        }
        // Instructions using HI and LO registers.
        case MULT:
          if (kArchVariant != kMips64r6) {
            set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
            set_register(HI, static_cast<int32_t>(i64hilo >> 32));
          } else {
            switch (instr->SaValue()) {
              case MUL_OP:
                set_register(rd_reg,
                    static_cast<int32_t>(i64hilo & 0xffffffff));
                break;
              case MUH_OP:
                set_register(rd_reg, static_cast<int32_t>(i64hilo >> 32));
                break;
              default:
                UNIMPLEMENTED_MIPS();
                break;
            }
          }
          break;
        case MULTU:
          set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
          set_register(HI, static_cast<int32_t>(u64hilo >> 32));
          break;
        case DMULT:  // DMULT == D_MUL_MUH.
          if (kArchVariant != kMips64r6) {
            set_register(LO, static_cast<int64_t>(i128resultL));
            set_register(HI, static_cast<int64_t>(i128resultH));
          } else {
            switch (instr->SaValue()) {
              case MUL_OP:
                set_register(rd_reg, static_cast<int64_t>(i128resultL));
                break;
              case MUH_OP:
                set_register(rd_reg, static_cast<int64_t>(i128resultH));
                break;
              default:
                UNIMPLEMENTED_MIPS();
                break;
            }
          }
          break;
        case DMULTU:
          UNIMPLEMENTED_MIPS();
          break;
        case DSLL:
          set_register(rd_reg, alu_out);
          break;
        case DIV:
        case DDIV:
          switch (kArchVariant) {
            case kMips64r2:
              // Divide by zero and overflow was not checked in the
              // configuration step - div and divu do not raise exceptions. On
              // division by 0 the result will be UNPREDICTABLE. On overflow
              // (INT_MIN/-1), return INT_MIN which is what the hardware does.
              if (rs == INT_MIN && rt == -1) {
                set_register(LO, INT_MIN);
                set_register(HI, 0);
              } else if (rt != 0) {
                set_register(LO, rs / rt);
                set_register(HI, rs % rt);
              }
              break;
            case kMips64r6:
              switch (instr->SaValue()) {
                case DIV_OP:
                  if (rs == INT_MIN && rt == -1) {
                    set_register(rd_reg, INT_MIN);
                  } else if (rt != 0) {
                    set_register(rd_reg, rs / rt);
                  }
                  break;
                case MOD_OP:
                  if (rs == INT_MIN && rt == -1) {
                    set_register(rd_reg, 0);
                  } else if (rt != 0) {
                    set_register(rd_reg, rs % rt);
                  }
                  break;
                default:
                  UNIMPLEMENTED_MIPS();
                  break;
              }
              break;
            default:
              break;
          }
          break;
        case DIVU:
          if (rt_u != 0) {
            set_register(LO, rs_u / rt_u);
            set_register(HI, rs_u % rt_u);
          }
          break;
        // Break and trap instructions.
        case BREAK:
        case TGE:
        case TGEU:
        case TLT:
        case TLTU:
        case TEQ:
        case TNE:
          if (do_interrupt) {
            SoftwareInterrupt(instr);
          }
          break;
        // Conditional moves.
        case MOVN:
          if (rt) {
            set_register(rd_reg, rs);
            TraceRegWr(rs);
          }
          break;
        case MOVCI: {
          uint32_t cc = instr->FBccValue();
          uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
          if (instr->Bit(16)) {  // Read Tf bit.
            if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
          } else {
            if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
          }
          break;
        }
        case MOVZ:
          if (!rt) {
            set_register(rd_reg, rs);
            TraceRegWr(rs);
          }
          break;
        default:  // For other special opcodes we do the default operation.
          set_register(rd_reg, alu_out);
          TraceRegWr(alu_out);
      }
      break;
    case SPECIAL2:
      switch (instr->FunctionFieldRaw()) {
        case MUL:
          set_register(rd_reg, alu_out);
          TraceRegWr(alu_out);
          // HI and LO are UNPREDICTABLE after the operation.
          set_register(LO, Unpredictable);
          set_register(HI, Unpredictable);
          break;
        default:  // For other special2 opcodes we do the default operation.
          set_register(rd_reg, alu_out);
      }
      break;
    case SPECIAL3:
      switch (instr->FunctionFieldRaw()) {
        case INS:
          // Ins instr leaves result in Rt, rather than Rd.
          set_register(rt_reg, alu_out);
          TraceRegWr(alu_out);
          break;
        case EXT:
          // Ext instr leaves result in Rt, rather than Rd.
          set_register(rt_reg, alu_out);
          TraceRegWr(alu_out);
          break;
        default:
          UNREACHABLE();
      }
      break;
    // Unimplemented opcodes raised an error in the configuration step before,
    // so we can use the default here to set the destination register in common
    // cases.
    default:
      set_register(rd_reg, alu_out);
      TraceRegWr(alu_out);
  }
}


// Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
void Simulator::DecodeTypeImmediate(Instruction* instr) {
  // Instruction fields.
  Opcode   op     = instr->OpcodeFieldRaw();
  int64_t  rs     = get_register(instr->RsValue());
  uint64_t rs_u   = static_cast<uint64_t>(rs);
  int64_t  rt_reg = instr->RtValue();  // Destination register.
  int64_t  rt     = get_register(rt_reg);
  int16_t  imm16  = instr->Imm16Value();

  int32_t  ft_reg = instr->FtValue();  // Destination register.
  int64_t  ft     = get_fpu_register(ft_reg);

  // Zero extended immediate.
  uint32_t  oe_imm16 = 0xffff & imm16;
  // Sign extended immediate.
  int32_t   se_imm16 = imm16;

  // Get current pc.
  int64_t current_pc = get_pc();
  // Next pc.
  int64_t next_pc = bad_ra;

  // Used for conditional branch instructions.
  bool do_branch = false;
  bool execute_branch_delay_instruction = false;

  // Used for arithmetic instructions.
  int64_t alu_out = 0;
  // Floating point.
  double fp_out = 0.0;
  uint32_t cc, cc_value, fcsr_cc;

  // Used for memory instructions.
  int64_t addr = 0x0;
  // Value to be written in memory.
  uint64_t mem_value = 0x0;
  // Alignment for 32-bit integers used in LWL, LWR, etc.
  const int kInt32AlignmentMask = sizeof(uint32_t) - 1;

  // ---------- Configuration (and execution for REGIMM).
  switch (op) {
    // ------------- COP1. Coprocessor instructions.
    case COP1:
      switch (instr->RsFieldRaw()) {
        case BC1:   // Branch on coprocessor condition.
          cc = instr->FBccValue();
          fcsr_cc = get_fcsr_condition_bit(cc);
          cc_value = test_fcsr_bit(fcsr_cc);
          do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
          execute_branch_delay_instruction = true;
          // Set next_pc.
          if (do_branch) {
            next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
          } else {
            next_pc = current_pc + kBranchReturnOffset;
          }
          break;
        case BC1EQZ:
          do_branch = (ft & 0x1) ? false : true;
          execute_branch_delay_instruction = true;
          // Set next_pc.
          if (do_branch) {
            next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
          } else {
            next_pc = current_pc + kBranchReturnOffset;
          }
          break;
        case BC1NEZ:
          do_branch = (ft & 0x1) ? true : false;
          execute_branch_delay_instruction = true;
          // Set next_pc.
          if (do_branch) {
            next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
          } else {
            next_pc = current_pc + kBranchReturnOffset;
          }
          break;
        default:
          UNREACHABLE();
      }
      break;
    // ------------- REGIMM class.
    case REGIMM:
      switch (instr->RtFieldRaw()) {
        case BLTZ:
          do_branch = (rs  < 0);
          break;
        case BLTZAL:
          do_branch = rs  < 0;
          break;
        case BGEZ:
          do_branch = rs >= 0;
          break;
        case BGEZAL:
          do_branch = rs >= 0;
          break;
        default:
          UNREACHABLE();
      }
      switch (instr->RtFieldRaw()) {
        case BLTZ:
        case BLTZAL:
        case BGEZ:
        case BGEZAL:
          // Branch instructions common part.
          execute_branch_delay_instruction = true;
          // Set next_pc.
          if (do_branch) {
            next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
            if (instr->IsLinkingInstruction()) {
              set_register(31, current_pc + kBranchReturnOffset);
            }
          } else {
            next_pc = current_pc + kBranchReturnOffset;
          }
        default:
          break;
        }
    break;  // case REGIMM.
    // ------------- Branch instructions.
    // When comparing to zero, the encoding of rt field is always 0, so we don't
    // need to replace rt with zero.
    case BEQ:
      do_branch = (rs == rt);
      break;
    case BNE:
      do_branch = rs != rt;
      break;
    case BLEZ:
      do_branch = rs <= 0;
      break;
    case BGTZ:
      do_branch = rs  > 0;
      break;
    // ------------- Arithmetic instructions.
    case ADDI:
    case DADDI:
      if (HaveSameSign(rs, se_imm16)) {
        if (rs > 0) {
          exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
        } else if (rs < 0) {
          exceptions[kIntegerUnderflow] =
              rs < (Registers::kMinValue - se_imm16);
        }
      }
      alu_out = rs + se_imm16;
      break;
    case ADDIU: {
        int32_t alu32_out = rs + se_imm16;
        // Sign-extend result of 32bit operation into 64bit register.
        alu_out = static_cast<int64_t>(alu32_out);
      }
      break;
    case DADDIU:
      alu_out = rs + se_imm16;
      break;
    case SLTI:
      alu_out = (rs < se_imm16) ? 1 : 0;
      break;
    case SLTIU:
      alu_out = (rs_u < static_cast<uint32_t>(se_imm16)) ? 1 : 0;
      break;
    case ANDI:
        alu_out = rs & oe_imm16;
      break;
    case ORI:
        alu_out = rs | oe_imm16;
      break;
    case XORI:
        alu_out = rs ^ oe_imm16;
      break;
    case LUI: {
        int32_t alu32_out = (oe_imm16 << 16);
        // Sign-extend result of 32bit operation into 64bit register.
        alu_out = static_cast<int64_t>(alu32_out);
      }
      break;
    // ------------- Memory instructions.
    case LB:
      addr = rs + se_imm16;
      alu_out = ReadB(addr);
      break;
    case LH:
      addr = rs + se_imm16;
      alu_out = ReadH(addr, instr);
      break;
    case LWL: {
      // al_offset is offset of the effective address within an aligned word.
      uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
      uint8_t byte_shift = kInt32AlignmentMask - al_offset;
      uint32_t mask = (1 << byte_shift * 8) - 1;
      addr = rs + se_imm16 - al_offset;
      alu_out = ReadW(addr, instr);
      alu_out <<= byte_shift * 8;
      alu_out |= rt & mask;
      break;
    }
    case LW:
      addr = rs + se_imm16;
      alu_out = ReadW(addr, instr);
      break;
    case LWU:
      addr = rs + se_imm16;
      alu_out = ReadWU(addr, instr);
      break;
    case LD:
      addr = rs + se_imm16;
      alu_out = Read2W(addr, instr);
      break;
    case LBU:
      addr = rs + se_imm16;
      alu_out = ReadBU(addr);
      break;
    case LHU:
      addr = rs + se_imm16;
      alu_out = ReadHU(addr, instr);
      break;
    case LWR: {
      // al_offset is offset of the effective address within an aligned word.
      uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
      uint8_t byte_shift = kInt32AlignmentMask - al_offset;
      uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
      addr = rs + se_imm16 - al_offset;
      alu_out = ReadW(addr, instr);
      alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
      alu_out |= rt & mask;
      break;
    }
    case SB:
      addr = rs + se_imm16;
      break;
    case SH:
      addr = rs + se_imm16;
      break;
    case SWL: {
      uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
      uint8_t byte_shift = kInt32AlignmentMask - al_offset;
      uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
      addr = rs + se_imm16 - al_offset;
      mem_value = ReadW(addr, instr) & mask;
      mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
      break;
    }
    case SW:
    case SD:
      addr = rs + se_imm16;
      break;
    case SWR: {
      uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
      uint32_t mask = (1 << al_offset * 8) - 1;
      addr = rs + se_imm16 - al_offset;
      mem_value = ReadW(addr, instr);
      mem_value = (rt << al_offset * 8) | (mem_value & mask);
      break;
    }
    case LWC1:
      addr = rs + se_imm16;
      alu_out = ReadW(addr, instr);
      break;
    case LDC1:
      addr = rs + se_imm16;
      fp_out = ReadD(addr, instr);
      break;
    case SWC1:
    case SDC1:
      addr = rs + se_imm16;
      break;
    default:
      UNREACHABLE();
  }

  // ---------- Raise exceptions triggered.
  SignalExceptions();

  // ---------- Execution.
  switch (op) {
    // ------------- Branch instructions.
    case BEQ:
    case BNE:
    case BLEZ:
    case BGTZ:
      // Branch instructions common part.
      execute_branch_delay_instruction = true;
      // Set next_pc.
      if (do_branch) {
        next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
        if (instr->IsLinkingInstruction()) {
          set_register(31, current_pc + 2* Instruction::kInstrSize);
        }
      } else {
        next_pc = current_pc + 2 * Instruction::kInstrSize;
      }
      break;
    // ------------- Arithmetic instructions.
    case ADDI:
    case DADDI:
    case ADDIU:
    case DADDIU:
    case SLTI:
    case SLTIU:
    case ANDI:
    case ORI:
    case XORI:
    case LUI:
      set_register(rt_reg, alu_out);
      TraceRegWr(alu_out);
      break;
    // ------------- Memory instructions.
    case LB:
    case LH:
    case LWL:
    case LW:
    case LWU:
    case LD:
    case LBU:
    case LHU:
    case LWR:
      set_register(rt_reg, alu_out);
      break;
    case SB:
      WriteB(addr, static_cast<int8_t>(rt));
      break;
    case SH:
      WriteH(addr, static_cast<uint16_t>(rt), instr);
      break;
    case SWL:
      WriteW(addr, mem_value, instr);
      break;
    case SW:
      WriteW(addr, rt, instr);
      break;
    case SD:
      Write2W(addr, rt, instr);
      break;
    case SWR:
      WriteW(addr, mem_value, instr);
      break;
    case LWC1:
      set_fpu_register(ft_reg, kFPUInvalidResult);  // Trash upper 32 bits.
      set_fpu_register_word(ft_reg, static_cast<int32_t>(alu_out));
      break;
    case LDC1:
      set_fpu_register_double(ft_reg, fp_out);
      break;
    case SWC1:
      addr = rs + se_imm16;
      WriteW(addr, get_fpu_register(ft_reg), instr);
      break;
    case SDC1:
      addr = rs + se_imm16;
      WriteD(addr, get_fpu_register_double(ft_reg), instr);
      break;
    default:
      break;
  }


  if (execute_branch_delay_instruction) {
    // Execute branch delay slot
    // We don't check for end_sim_pc. First it should not be met as the current
    // pc is valid. Secondly a jump should always execute its branch delay slot.
    Instruction* branch_delay_instr =
      reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize);
    BranchDelayInstructionDecode(branch_delay_instr);
  }

  // If needed update pc after the branch delay execution.
  if (next_pc != bad_ra) {
    set_pc(next_pc);
  }
}


// Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
void Simulator::DecodeTypeJump(Instruction* instr) {
  // Get current pc.
  int32_t current_pc = get_pc();
  // Get unchanged bits of pc.
  int32_t pc_high_bits = current_pc & 0xf0000000;
  // Next pc.
  int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);

  // Execute branch delay slot.
  // We don't check for end_sim_pc. First it should not be met as the current pc
  // is valid. Secondly a jump should always execute its branch delay slot.
  Instruction* branch_delay_instr =
      reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
  BranchDelayInstructionDecode(branch_delay_instr);

  // Update pc and ra if necessary.
  // Do this after the branch delay execution.
  if (instr->IsLinkingInstruction()) {
    set_register(31, current_pc + 2 * Instruction::kInstrSize);
  }
  set_pc(next_pc);
  pc_modified_ = true;
}


// Executes the current instruction.
void Simulator::InstructionDecode(Instruction* instr) {
  if (v8::internal::FLAG_check_icache) {
    CheckICache(isolate_->simulator_i_cache(), instr);
  }
  pc_modified_ = false;

  v8::internal::EmbeddedVector<char, 256> buffer;

  if (::v8::internal::FLAG_trace_sim) {
    SNPrintF(trace_buf_, " ");
    disasm::NameConverter converter;
    disasm::Disassembler dasm(converter);
    // Use a reasonably large buffer.
    dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
  }

  switch (instr->InstructionType()) {
    case Instruction::kRegisterType:
      DecodeTypeRegister(instr);
      break;
    case Instruction::kImmediateType:
      DecodeTypeImmediate(instr);
      break;
    case Instruction::kJumpType:
      DecodeTypeJump(instr);
      break;
    default:
      UNSUPPORTED();
  }

  if (::v8::internal::FLAG_trace_sim) {
    PrintF("  0x%08lx  %-44s   %s\n", reinterpret_cast<intptr_t>(instr),
        buffer.start(), trace_buf_.start());
  }

  if (!pc_modified_) {
    set_register(pc, reinterpret_cast<int64_t>(instr) +
                 Instruction::kInstrSize);
  }
}



void Simulator::Execute() {
  // 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.
  int64_t program_counter = get_pc();
  if (::v8::internal::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 != end_sim_pc) {
      Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
      icount_++;
      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 instuction count.
    while (program_counter != end_sim_pc) {
      Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
      icount_++;
      if (icount_ == static_cast<int64_t>(::v8::internal::FLAG_stop_sim_at)) {
        MipsDebugger dbg(this);
        dbg.Debug();
      } else {
        InstructionDecode(instr);
      }
      program_counter = get_pc();
    }
  }
}


void Simulator::CallInternal(byte* entry) {
  // Prepare to execute the code at entry.
  set_register(pc, reinterpret_cast<int64_t>(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(ra, end_sim_pc);

  // 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.
  int64_t s0_val = get_register(s0);
  int64_t s1_val = get_register(s1);
  int64_t s2_val = get_register(s2);
  int64_t s3_val = get_register(s3);
  int64_t s4_val = get_register(s4);
  int64_t s5_val = get_register(s5);
  int64_t s6_val = get_register(s6);
  int64_t s7_val = get_register(s7);
  int64_t gp_val = get_register(gp);
  int64_t sp_val = get_register(sp);
  int64_t fp_val = get_register(fp);

  // Set up the callee-saved registers with a known value. To be able to check
  // that they are preserved properly across JS execution.
  int64_t callee_saved_value = icount_;
  set_register(s0, callee_saved_value);
  set_register(s1, callee_saved_value);
  set_register(s2, callee_saved_value);
  set_register(s3, callee_saved_value);
  set_register(s4, callee_saved_value);
  set_register(s5, callee_saved_value);
  set_register(s6, callee_saved_value);
  set_register(s7, callee_saved_value);
  set_register(gp, callee_saved_value);
  set_register(fp, callee_saved_value);

  // Start the simulation.
  Execute();

  // Check that the callee-saved registers have been preserved.
  CHECK_EQ(callee_saved_value, get_register(s0));
  CHECK_EQ(callee_saved_value, get_register(s1));
  CHECK_EQ(callee_saved_value, get_register(s2));
  CHECK_EQ(callee_saved_value, get_register(s3));
  CHECK_EQ(callee_saved_value, get_register(s4));
  CHECK_EQ(callee_saved_value, get_register(s5));
  CHECK_EQ(callee_saved_value, get_register(s6));
  CHECK_EQ(callee_saved_value, get_register(s7));
  CHECK_EQ(callee_saved_value, get_register(gp));
  CHECK_EQ(callee_saved_value, get_register(fp));

  // Restore callee-saved registers with the original value.
  set_register(s0, s0_val);
  set_register(s1, s1_val);
  set_register(s2, s2_val);
  set_register(s3, s3_val);
  set_register(s4, s4_val);
  set_register(s5, s5_val);
  set_register(s6, s6_val);
  set_register(s7, s7_val);
  set_register(gp, gp_val);
  set_register(sp, sp_val);
  set_register(fp, fp_val);
}


int64_t Simulator::Call(byte* entry, int argument_count, ...) {
  const int kRegisterPassedArguments = (kMipsAbi == kN64) ? 8 : 4;
  va_list parameters;
  va_start(parameters, argument_count);
  // Set up arguments.

  // First four arguments passed in registers in both ABI's.
  DCHECK(argument_count >= 4);
  set_register(a0, va_arg(parameters, int64_t));
  set_register(a1, va_arg(parameters, int64_t));
  set_register(a2, va_arg(parameters, int64_t));
  set_register(a3, va_arg(parameters, int64_t));

  if (kMipsAbi == kN64) {
    // Up to eight arguments passed in registers in N64 ABI.
    // TODO(plind): N64 ABI calls these regs a4 - a7. Clarify this.
    if (argument_count >= 5) set_register(a4, va_arg(parameters, int64_t));
    if (argument_count >= 6) set_register(a5, va_arg(parameters, int64_t));
    if (argument_count >= 7) set_register(a6, va_arg(parameters, int64_t));
    if (argument_count >= 8) set_register(a7, va_arg(parameters, int64_t));
  }

  // Remaining arguments passed on stack.
  int64_t original_stack = get_register(sp);
  // Compute position of stack on entry to generated code.
  int stack_args_count = (argument_count > kRegisterPassedArguments) ?
                         (argument_count - kRegisterPassedArguments) : 0;
  int stack_args_size = stack_args_count * sizeof(int64_t) + kCArgsSlotsSize;
  int64_t entry_stack = original_stack - stack_args_size;

  if (base::OS::ActivationFrameAlignment() != 0) {
    entry_stack &= -base::OS::ActivationFrameAlignment();
  }
  // Store remaining arguments on stack, from low to high memory.
  intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
  for (int i = kRegisterPassedArguments; i < argument_count; i++) {
    int stack_index = i - kRegisterPassedArguments + kCArgSlotCount;
    stack_argument[stack_index] = va_arg(parameters, int64_t);
  }
  va_end(parameters);
  set_register(sp, entry_stack);

  CallInternal(entry);

  // Pop stack passed arguments.
  CHECK_EQ(entry_stack, get_register(sp));
  set_register(sp, original_stack);

  int64_t result = get_register(v0);
  return result;
}


double Simulator::CallFP(byte* entry, double d0, double d1) {
  if (!IsMipsSoftFloatABI) {
    const FPURegister fparg2 = (kMipsAbi == kN64) ? f13 : f14;
    set_fpu_register_double(f12, d0);
    set_fpu_register_double(fparg2, d1);
  } else {
    int buffer[2];
    DCHECK(sizeof(buffer[0]) * 2 == sizeof(d0));
    memcpy(buffer, &d0, sizeof(d0));
    set_dw_register(a0, buffer);
    memcpy(buffer, &d1, sizeof(d1));
    set_dw_register(a2, buffer);
  }
  CallInternal(entry);
  if (!IsMipsSoftFloatABI) {
    return get_fpu_register_double(f0);
  } else {
    return get_double_from_register_pair(v0);
  }
}


uintptr_t Simulator::PushAddress(uintptr_t address) {
  int64_t new_sp = get_register(sp) - sizeof(uintptr_t);
  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
  *stack_slot = address;
  set_register(sp, new_sp);
  return new_sp;
}


uintptr_t Simulator::PopAddress() {
  int64_t current_sp = get_register(sp);
  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
  uintptr_t address = *stack_slot;
  set_register(sp, current_sp + sizeof(uintptr_t));
  return address;
}


#undef UNSUPPORTED

} }  // namespace v8::internal

#endif  // USE_SIMULATOR

#endif  // V8_TARGET_ARCH_MIPS64
