Home | History | Annotate | Download | only in mips64
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <limits.h>
      6 #include <stdarg.h>
      7 #include <stdlib.h>
      8 #include <cmath>
      9 
     10 #if V8_TARGET_ARCH_MIPS64
     11 
     12 #include "src/assembler.h"
     13 #include "src/base/bits.h"
     14 #include "src/codegen.h"
     15 #include "src/disasm.h"
     16 #include "src/mips64/constants-mips64.h"
     17 #include "src/mips64/simulator-mips64.h"
     18 #include "src/ostreams.h"
     19 #include "src/runtime/runtime-utils.h"
     20 
     21 // Only build the simulator if not compiling for real MIPS hardware.
     22 #if defined(USE_SIMULATOR)
     23 
     24 namespace v8 {
     25 namespace internal {
     26 
     27 // Util functions.
     28 inline bool HaveSameSign(int64_t a, int64_t b) { return ((a ^ b) >= 0); }
     29 
     30 uint32_t get_fcsr_condition_bit(uint32_t cc) {
     31   if (cc == 0) {
     32     return 23;
     33   } else {
     34     return 24 + cc;
     35   }
     36 }
     37 
     38 
     39 static int64_t MultiplyHighSigned(int64_t u, int64_t v) {
     40   uint64_t u0, v0, w0;
     41   int64_t u1, v1, w1, w2, t;
     42 
     43   u0 = u & 0xffffffffL;
     44   u1 = u >> 32;
     45   v0 = v & 0xffffffffL;
     46   v1 = v >> 32;
     47 
     48   w0 = u0 * v0;
     49   t = u1 * v0 + (w0 >> 32);
     50   w1 = t & 0xffffffffL;
     51   w2 = t >> 32;
     52   w1 = u0 * v1 + w1;
     53 
     54   return u1 * v1 + w2 + (w1 >> 32);
     55 }
     56 
     57 
     58 // This macro provides a platform independent use of sscanf. The reason for
     59 // SScanF not being implemented in a platform independent was through
     60 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time
     61 // Library does not provide vsscanf.
     62 #define SScanF sscanf  // NOLINT
     63 
     64 // The MipsDebugger class is used by the simulator while debugging simulated
     65 // code.
     66 class MipsDebugger {
     67  public:
     68   explicit MipsDebugger(Simulator* sim) : sim_(sim) { }
     69 
     70   void Stop(Instruction* instr);
     71   void Debug();
     72   // Print all registers with a nice formatting.
     73   void PrintAllRegs();
     74   void PrintAllRegsIncludingFPU();
     75 
     76  private:
     77   // We set the breakpoint code to 0xfffff to easily recognize it.
     78   static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6;
     79   static const Instr kNopInstr =  0x0;
     80 
     81   Simulator* sim_;
     82 
     83   int64_t GetRegisterValue(int regnum);
     84   int64_t GetFPURegisterValue(int regnum);
     85   float GetFPURegisterValueFloat(int regnum);
     86   double GetFPURegisterValueDouble(int regnum);
     87   bool GetValue(const char* desc, int64_t* value);
     88 
     89   // Set or delete a breakpoint. Returns true if successful.
     90   bool SetBreakpoint(Instruction* breakpc);
     91   bool DeleteBreakpoint(Instruction* breakpc);
     92 
     93   // Undo and redo all breakpoints. This is needed to bracket disassembly and
     94   // execution to skip past breakpoints when run from the debugger.
     95   void UndoBreakpoints();
     96   void RedoBreakpoints();
     97 };
     98 
     99 inline void UNSUPPORTED() { printf("Sim: Unsupported instruction.\n"); }
    100 
    101 void MipsDebugger::Stop(Instruction* instr) {
    102   // Get the stop code.
    103   uint32_t code = instr->Bits(25, 6);
    104   PrintF("Simulator hit (%u)\n", code);
    105   // TODO(yuyin): 2 -> 3?
    106   sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstrSize);
    107   Debug();
    108 }
    109 
    110 int64_t MipsDebugger::GetRegisterValue(int regnum) {
    111   if (regnum == kNumSimuRegisters) {
    112     return sim_->get_pc();
    113   } else {
    114     return sim_->get_register(regnum);
    115   }
    116 }
    117 
    118 
    119 int64_t MipsDebugger::GetFPURegisterValue(int regnum) {
    120   if (regnum == kNumFPURegisters) {
    121     return sim_->get_pc();
    122   } else {
    123     return sim_->get_fpu_register(regnum);
    124   }
    125 }
    126 
    127 
    128 float MipsDebugger::GetFPURegisterValueFloat(int regnum) {
    129   if (regnum == kNumFPURegisters) {
    130     return sim_->get_pc();
    131   } else {
    132     return sim_->get_fpu_register_float(regnum);
    133   }
    134 }
    135 
    136 
    137 double MipsDebugger::GetFPURegisterValueDouble(int regnum) {
    138   if (regnum == kNumFPURegisters) {
    139     return sim_->get_pc();
    140   } else {
    141     return sim_->get_fpu_register_double(regnum);
    142   }
    143 }
    144 
    145 
    146 bool MipsDebugger::GetValue(const char* desc, int64_t* value) {
    147   int regnum = Registers::Number(desc);
    148   int fpuregnum = FPURegisters::Number(desc);
    149 
    150   if (regnum != kInvalidRegister) {
    151     *value = GetRegisterValue(regnum);
    152     return true;
    153   } else if (fpuregnum != kInvalidFPURegister) {
    154     *value = GetFPURegisterValue(fpuregnum);
    155     return true;
    156   } else if (strncmp(desc, "0x", 2) == 0) {
    157     return SScanF(desc + 2, "%" SCNx64,
    158                   reinterpret_cast<uint64_t*>(value)) == 1;
    159   } else {
    160     return SScanF(desc, "%" SCNu64, reinterpret_cast<uint64_t*>(value)) == 1;
    161   }
    162   return false;
    163 }
    164 
    165 
    166 bool MipsDebugger::SetBreakpoint(Instruction* breakpc) {
    167   // Check if a breakpoint can be set. If not return without any side-effects.
    168   if (sim_->break_pc_ != NULL) {
    169     return false;
    170   }
    171 
    172   // Set the breakpoint.
    173   sim_->break_pc_ = breakpc;
    174   sim_->break_instr_ = breakpc->InstructionBits();
    175   // Not setting the breakpoint instruction in the code itself. It will be set
    176   // when the debugger shell continues.
    177   return true;
    178 }
    179 
    180 
    181 bool MipsDebugger::DeleteBreakpoint(Instruction* breakpc) {
    182   if (sim_->break_pc_ != NULL) {
    183     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    184   }
    185 
    186   sim_->break_pc_ = NULL;
    187   sim_->break_instr_ = 0;
    188   return true;
    189 }
    190 
    191 
    192 void MipsDebugger::UndoBreakpoints() {
    193   if (sim_->break_pc_ != NULL) {
    194     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    195   }
    196 }
    197 
    198 
    199 void MipsDebugger::RedoBreakpoints() {
    200   if (sim_->break_pc_ != NULL) {
    201     sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
    202   }
    203 }
    204 
    205 
    206 void MipsDebugger::PrintAllRegs() {
    207 #define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)
    208 
    209   PrintF("\n");
    210   // at, v0, a0.
    211   PrintF("%3s: 0x%016" PRIx64 " %14" PRId64 "\t%3s: 0x%016" PRIx64 " %14" PRId64
    212          "\t%3s: 0x%016" PRIx64 " %14" PRId64 "\n",
    213          REG_INFO(1), REG_INFO(2), REG_INFO(4));
    214   // v1, a1.
    215   PrintF("%34s\t%3s: 0x%016" PRIx64 "  %14" PRId64 " \t%3s: 0x%016" PRIx64
    216          "  %14" PRId64 " \n",
    217          "", REG_INFO(3), REG_INFO(5));
    218   // a2.
    219   PrintF("%34s\t%34s\t%3s: 0x%016" PRIx64 "  %14" PRId64 " \n", "", "",
    220          REG_INFO(6));
    221   // a3.
    222   PrintF("%34s\t%34s\t%3s: 0x%016" PRIx64 "  %14" PRId64 " \n", "", "",
    223          REG_INFO(7));
    224   PrintF("\n");
    225   // a4-t3, s0-s7
    226   for (int i = 0; i < 8; i++) {
    227     PrintF("%3s: 0x%016" PRIx64 "  %14" PRId64 " \t%3s: 0x%016" PRIx64
    228            "  %14" PRId64 " \n",
    229            REG_INFO(8 + i), REG_INFO(16 + i));
    230   }
    231   PrintF("\n");
    232   // t8, k0, LO.
    233   PrintF("%3s: 0x%016" PRIx64 "  %14" PRId64 " \t%3s: 0x%016" PRIx64
    234          "  %14" PRId64 " \t%3s: 0x%016" PRIx64 "  %14" PRId64 " \n",
    235          REG_INFO(24), REG_INFO(26), REG_INFO(32));
    236   // t9, k1, HI.
    237   PrintF("%3s: 0x%016" PRIx64 "  %14" PRId64 " \t%3s: 0x%016" PRIx64
    238          "  %14" PRId64 " \t%3s: 0x%016" PRIx64 "  %14" PRId64 " \n",
    239          REG_INFO(25), REG_INFO(27), REG_INFO(33));
    240   // sp, fp, gp.
    241   PrintF("%3s: 0x%016" PRIx64 "  %14" PRId64 " \t%3s: 0x%016" PRIx64
    242          "  %14" PRId64 " \t%3s: 0x%016" PRIx64 "  %14" PRId64 " \n",
    243          REG_INFO(29), REG_INFO(30), REG_INFO(28));
    244   // pc.
    245   PrintF("%3s: 0x%016" PRIx64 "  %14" PRId64 " \t%3s: 0x%016" PRIx64
    246          "  %14" PRId64 " \n",
    247          REG_INFO(31), REG_INFO(34));
    248 
    249 #undef REG_INFO
    250 #undef FPU_REG_INFO
    251 }
    252 
    253 
    254 void MipsDebugger::PrintAllRegsIncludingFPU() {
    255 #define FPU_REG_INFO(n) FPURegisters::Name(n), \
    256         GetFPURegisterValue(n), \
    257         GetFPURegisterValueDouble(n)
    258 
    259   PrintAllRegs();
    260 
    261   PrintF("\n\n");
    262   // f0, f1, f2, ... f31.
    263   // TODO(plind): consider printing 2 columns for space efficiency.
    264   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(0));
    265   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(1));
    266   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(2));
    267   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(3));
    268   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(4));
    269   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(5));
    270   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(6));
    271   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(7));
    272   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(8));
    273   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(9));
    274   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(10));
    275   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(11));
    276   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(12));
    277   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(13));
    278   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(14));
    279   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(15));
    280   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(16));
    281   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(17));
    282   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(18));
    283   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(19));
    284   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(20));
    285   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(21));
    286   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(22));
    287   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(23));
    288   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(24));
    289   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(25));
    290   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(26));
    291   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(27));
    292   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(28));
    293   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(29));
    294   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(30));
    295   PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n", FPU_REG_INFO(31));
    296 
    297 #undef REG_INFO
    298 #undef FPU_REG_INFO
    299 }
    300 
    301 
    302 void MipsDebugger::Debug() {
    303   intptr_t last_pc = -1;
    304   bool done = false;
    305 
    306 #define COMMAND_SIZE 63
    307 #define ARG_SIZE 255
    308 
    309 #define STR(a) #a
    310 #define XSTR(a) STR(a)
    311 
    312   char cmd[COMMAND_SIZE + 1];
    313   char arg1[ARG_SIZE + 1];
    314   char arg2[ARG_SIZE + 1];
    315   char* argv[3] = { cmd, arg1, arg2 };
    316 
    317   // Make sure to have a proper terminating character if reaching the limit.
    318   cmd[COMMAND_SIZE] = 0;
    319   arg1[ARG_SIZE] = 0;
    320   arg2[ARG_SIZE] = 0;
    321 
    322   // Undo all set breakpoints while running in the debugger shell. This will
    323   // make them invisible to all commands.
    324   UndoBreakpoints();
    325 
    326   while (!done && (sim_->get_pc() != Simulator::end_sim_pc)) {
    327     if (last_pc != sim_->get_pc()) {
    328       disasm::NameConverter converter;
    329       disasm::Disassembler dasm(converter);
    330       // Use a reasonably large buffer.
    331       v8::internal::EmbeddedVector<char, 256> buffer;
    332       dasm.InstructionDecode(buffer,
    333                              reinterpret_cast<byte*>(sim_->get_pc()));
    334       PrintF("  0x%016" PRIx64 "   %s\n", sim_->get_pc(), buffer.start());
    335       last_pc = sim_->get_pc();
    336     }
    337     char* line = ReadLine("sim> ");
    338     if (line == NULL) {
    339       break;
    340     } else {
    341       char* last_input = sim_->last_debugger_input();
    342       if (strcmp(line, "\n") == 0 && last_input != NULL) {
    343         line = last_input;
    344       } else {
    345         // Ownership is transferred to sim_;
    346         sim_->set_last_debugger_input(line);
    347       }
    348       // Use sscanf to parse the individual parts of the command line. At the
    349       // moment no command expects more than two parameters.
    350       int argc = SScanF(line,
    351                         "%" XSTR(COMMAND_SIZE) "s "
    352                         "%" XSTR(ARG_SIZE) "s "
    353                         "%" XSTR(ARG_SIZE) "s",
    354                         cmd, arg1, arg2);
    355       if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
    356         Instruction* instr = reinterpret_cast<Instruction*>(sim_->get_pc());
    357         if (!(instr->IsTrap()) ||
    358             instr->InstructionBits() == rtCallRedirInstr) {
    359           sim_->InstructionDecode(
    360               reinterpret_cast<Instruction*>(sim_->get_pc()));
    361         } else {
    362           // Allow si to jump over generated breakpoints.
    363           PrintF("/!\\ Jumping over generated breakpoint.\n");
    364           sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
    365         }
    366       } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
    367         // Execute the one instruction we broke at with breakpoints disabled.
    368         sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
    369         // Leave the debugger shell.
    370         done = true;
    371       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
    372         if (argc == 2) {
    373           int64_t value;
    374           double dvalue;
    375           if (strcmp(arg1, "all") == 0) {
    376             PrintAllRegs();
    377           } else if (strcmp(arg1, "allf") == 0) {
    378             PrintAllRegsIncludingFPU();
    379           } else {
    380             int regnum = Registers::Number(arg1);
    381             int fpuregnum = FPURegisters::Number(arg1);
    382 
    383             if (regnum != kInvalidRegister) {
    384               value = GetRegisterValue(regnum);
    385               PrintF("%s: 0x%08" PRIx64 "  %" PRId64 "  \n", arg1, value,
    386                      value);
    387             } else if (fpuregnum != kInvalidFPURegister) {
    388               value = GetFPURegisterValue(fpuregnum);
    389               dvalue = GetFPURegisterValueDouble(fpuregnum);
    390               PrintF("%3s: 0x%016" PRIx64 "  %16.4e\n",
    391                      FPURegisters::Name(fpuregnum), value, dvalue);
    392             } else {
    393               PrintF("%s unrecognized\n", arg1);
    394             }
    395           }
    396         } else {
    397           if (argc == 3) {
    398             if (strcmp(arg2, "single") == 0) {
    399               int64_t value;
    400               float fvalue;
    401               int fpuregnum = FPURegisters::Number(arg1);
    402 
    403               if (fpuregnum != kInvalidFPURegister) {
    404                 value = GetFPURegisterValue(fpuregnum);
    405                 value &= 0xffffffffUL;
    406                 fvalue = GetFPURegisterValueFloat(fpuregnum);
    407                 PrintF("%s: 0x%08" PRIx64 "  %11.4e\n", arg1, value, fvalue);
    408               } else {
    409                 PrintF("%s unrecognized\n", arg1);
    410               }
    411             } else {
    412               PrintF("print <fpu register> single\n");
    413             }
    414           } else {
    415             PrintF("print <register> or print <fpu register> single\n");
    416           }
    417         }
    418       } else if ((strcmp(cmd, "po") == 0)
    419                  || (strcmp(cmd, "printobject") == 0)) {
    420         if (argc == 2) {
    421           int64_t value;
    422           OFStream os(stdout);
    423           if (GetValue(arg1, &value)) {
    424             Object* obj = reinterpret_cast<Object*>(value);
    425             os << arg1 << ": \n";
    426 #ifdef DEBUG
    427             obj->Print(os);
    428             os << "\n";
    429 #else
    430             os << Brief(obj) << "\n";
    431 #endif
    432           } else {
    433             os << arg1 << " unrecognized\n";
    434           }
    435         } else {
    436           PrintF("printobject <value>\n");
    437         }
    438       } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
    439         int64_t* cur = NULL;
    440         int64_t* end = NULL;
    441         int next_arg = 1;
    442 
    443         if (strcmp(cmd, "stack") == 0) {
    444           cur = reinterpret_cast<int64_t*>(sim_->get_register(Simulator::sp));
    445         } else {  // Command "mem".
    446           int64_t value;
    447           if (!GetValue(arg1, &value)) {
    448             PrintF("%s unrecognized\n", arg1);
    449             continue;
    450           }
    451           cur = reinterpret_cast<int64_t*>(value);
    452           next_arg++;
    453         }
    454 
    455         int64_t words;
    456         if (argc == next_arg) {
    457           words = 10;
    458         } else {
    459           if (!GetValue(argv[next_arg], &words)) {
    460             words = 10;
    461           }
    462         }
    463         end = cur + words;
    464 
    465         while (cur < end) {
    466           PrintF("  0x%012" PRIxPTR " :  0x%016" PRIx64 "  %14" PRId64 " ",
    467                  reinterpret_cast<intptr_t>(cur), *cur, *cur);
    468           HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
    469           int64_t value = *cur;
    470           Heap* current_heap = sim_->isolate_->heap();
    471           if (((value & 1) == 0) ||
    472               current_heap->ContainsSlow(obj->address())) {
    473             PrintF(" (");
    474             if ((value & 1) == 0) {
    475               PrintF("smi %d", static_cast<int>(value >> 32));
    476             } else {
    477               obj->ShortPrint();
    478             }
    479             PrintF(")");
    480           }
    481           PrintF("\n");
    482           cur++;
    483         }
    484 
    485       } else if ((strcmp(cmd, "disasm") == 0) ||
    486                  (strcmp(cmd, "dpc") == 0) ||
    487                  (strcmp(cmd, "di") == 0)) {
    488         disasm::NameConverter converter;
    489         disasm::Disassembler dasm(converter);
    490         // Use a reasonably large buffer.
    491         v8::internal::EmbeddedVector<char, 256> buffer;
    492 
    493         byte* cur = NULL;
    494         byte* end = NULL;
    495 
    496         if (argc == 1) {
    497           cur = reinterpret_cast<byte*>(sim_->get_pc());
    498           end = cur + (10 * Instruction::kInstrSize);
    499         } else if (argc == 2) {
    500           int regnum = Registers::Number(arg1);
    501           if (regnum != kInvalidRegister || strncmp(arg1, "0x", 2) == 0) {
    502             // The argument is an address or a register name.
    503             int64_t value;
    504             if (GetValue(arg1, &value)) {
    505               cur = reinterpret_cast<byte*>(value);
    506               // Disassemble 10 instructions at <arg1>.
    507               end = cur + (10 * Instruction::kInstrSize);
    508             }
    509           } else {
    510             // The argument is the number of instructions.
    511             int64_t value;
    512             if (GetValue(arg1, &value)) {
    513               cur = reinterpret_cast<byte*>(sim_->get_pc());
    514               // Disassemble <arg1> instructions.
    515               end = cur + (value * Instruction::kInstrSize);
    516             }
    517           }
    518         } else {
    519           int64_t value1;
    520           int64_t value2;
    521           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
    522             cur = reinterpret_cast<byte*>(value1);
    523             end = cur + (value2 * Instruction::kInstrSize);
    524           }
    525         }
    526 
    527         while (cur < end) {
    528           dasm.InstructionDecode(buffer, cur);
    529           PrintF("  0x%08" PRIxPTR "   %s\n", reinterpret_cast<intptr_t>(cur),
    530                  buffer.start());
    531           cur += Instruction::kInstrSize;
    532         }
    533       } else if (strcmp(cmd, "gdb") == 0) {
    534         PrintF("relinquishing control to gdb\n");
    535         v8::base::OS::DebugBreak();
    536         PrintF("regaining control from gdb\n");
    537       } else if (strcmp(cmd, "break") == 0) {
    538         if (argc == 2) {
    539           int64_t value;
    540           if (GetValue(arg1, &value)) {
    541             if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
    542               PrintF("setting breakpoint failed\n");
    543             }
    544           } else {
    545             PrintF("%s unrecognized\n", arg1);
    546           }
    547         } else {
    548           PrintF("break <address>\n");
    549         }
    550       } else if (strcmp(cmd, "del") == 0) {
    551         if (!DeleteBreakpoint(NULL)) {
    552           PrintF("deleting breakpoint failed\n");
    553         }
    554       } else if (strcmp(cmd, "flags") == 0) {
    555         PrintF("No flags on MIPS !\n");
    556       } else if (strcmp(cmd, "stop") == 0) {
    557         int64_t value;
    558         intptr_t stop_pc = sim_->get_pc() -
    559             2 * Instruction::kInstrSize;
    560         Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
    561         Instruction* msg_address =
    562           reinterpret_cast<Instruction*>(stop_pc +
    563               Instruction::kInstrSize);
    564         if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
    565           // Remove the current stop.
    566           if (sim_->IsStopInstruction(stop_instr)) {
    567             stop_instr->SetInstructionBits(kNopInstr);
    568             msg_address->SetInstructionBits(kNopInstr);
    569           } else {
    570             PrintF("Not at debugger stop.\n");
    571           }
    572         } else if (argc == 3) {
    573           // Print information about all/the specified breakpoint(s).
    574           if (strcmp(arg1, "info") == 0) {
    575             if (strcmp(arg2, "all") == 0) {
    576               PrintF("Stop information:\n");
    577               for (uint32_t i = kMaxWatchpointCode + 1;
    578                    i <= kMaxStopCode;
    579                    i++) {
    580                 sim_->PrintStopInfo(i);
    581               }
    582             } else if (GetValue(arg2, &value)) {
    583               sim_->PrintStopInfo(value);
    584             } else {
    585               PrintF("Unrecognized argument.\n");
    586             }
    587           } else if (strcmp(arg1, "enable") == 0) {
    588             // Enable all/the specified breakpoint(s).
    589             if (strcmp(arg2, "all") == 0) {
    590               for (uint32_t i = kMaxWatchpointCode + 1;
    591                    i <= kMaxStopCode;
    592                    i++) {
    593                 sim_->EnableStop(i);
    594               }
    595             } else if (GetValue(arg2, &value)) {
    596               sim_->EnableStop(value);
    597             } else {
    598               PrintF("Unrecognized argument.\n");
    599             }
    600           } else if (strcmp(arg1, "disable") == 0) {
    601             // Disable all/the specified breakpoint(s).
    602             if (strcmp(arg2, "all") == 0) {
    603               for (uint32_t i = kMaxWatchpointCode + 1;
    604                    i <= kMaxStopCode;
    605                    i++) {
    606                 sim_->DisableStop(i);
    607               }
    608             } else if (GetValue(arg2, &value)) {
    609               sim_->DisableStop(value);
    610             } else {
    611               PrintF("Unrecognized argument.\n");
    612             }
    613           }
    614         } else {
    615           PrintF("Wrong usage. Use help command for more information.\n");
    616         }
    617       } else if ((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0)) {
    618         // Print registers and disassemble.
    619         PrintAllRegs();
    620         PrintF("\n");
    621 
    622         disasm::NameConverter converter;
    623         disasm::Disassembler dasm(converter);
    624         // Use a reasonably large buffer.
    625         v8::internal::EmbeddedVector<char, 256> buffer;
    626 
    627         byte* cur = NULL;
    628         byte* end = NULL;
    629 
    630         if (argc == 1) {
    631           cur = reinterpret_cast<byte*>(sim_->get_pc());
    632           end = cur + (10 * Instruction::kInstrSize);
    633         } else if (argc == 2) {
    634           int64_t value;
    635           if (GetValue(arg1, &value)) {
    636             cur = reinterpret_cast<byte*>(value);
    637             // no length parameter passed, assume 10 instructions
    638             end = cur + (10 * Instruction::kInstrSize);
    639           }
    640         } else {
    641           int64_t value1;
    642           int64_t value2;
    643           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
    644             cur = reinterpret_cast<byte*>(value1);
    645             end = cur + (value2 * Instruction::kInstrSize);
    646           }
    647         }
    648 
    649         while (cur < end) {
    650           dasm.InstructionDecode(buffer, cur);
    651           PrintF("  0x%08" PRIxPTR "   %s\n", reinterpret_cast<intptr_t>(cur),
    652                  buffer.start());
    653           cur += Instruction::kInstrSize;
    654         }
    655       } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
    656         PrintF("cont\n");
    657         PrintF("  continue execution (alias 'c')\n");
    658         PrintF("stepi\n");
    659         PrintF("  step one instruction (alias 'si')\n");
    660         PrintF("print <register>\n");
    661         PrintF("  print register content (alias 'p')\n");
    662         PrintF("  use register name 'all' to print all registers\n");
    663         PrintF("printobject <register>\n");
    664         PrintF("  print an object from a register (alias 'po')\n");
    665         PrintF("stack [<words>]\n");
    666         PrintF("  dump stack content, default dump 10 words)\n");
    667         PrintF("mem <address> [<words>]\n");
    668         PrintF("  dump memory content, default dump 10 words)\n");
    669         PrintF("flags\n");
    670         PrintF("  print flags\n");
    671         PrintF("disasm [<instructions>]\n");
    672         PrintF("disasm [<address/register>]\n");
    673         PrintF("disasm [[<address/register>] <instructions>]\n");
    674         PrintF("  disassemble code, default is 10 instructions\n");
    675         PrintF("  from pc (alias 'di')\n");
    676         PrintF("gdb\n");
    677         PrintF("  enter gdb\n");
    678         PrintF("break <address>\n");
    679         PrintF("  set a break point on the address\n");
    680         PrintF("del\n");
    681         PrintF("  delete the breakpoint\n");
    682         PrintF("stop feature:\n");
    683         PrintF("  Description:\n");
    684         PrintF("    Stops are debug instructions inserted by\n");
    685         PrintF("    the Assembler::stop() function.\n");
    686         PrintF("    When hitting a stop, the Simulator will\n");
    687         PrintF("    stop and and give control to the Debugger.\n");
    688         PrintF("    All stop codes are watched:\n");
    689         PrintF("    - They can be enabled / disabled: the Simulator\n");
    690         PrintF("       will / won't stop when hitting them.\n");
    691         PrintF("    - The Simulator keeps track of how many times they \n");
    692         PrintF("      are met. (See the info command.) Going over a\n");
    693         PrintF("      disabled stop still increases its counter. \n");
    694         PrintF("  Commands:\n");
    695         PrintF("    stop info all/<code> : print infos about number <code>\n");
    696         PrintF("      or all stop(s).\n");
    697         PrintF("    stop enable/disable all/<code> : enables / disables\n");
    698         PrintF("      all or number <code> stop(s)\n");
    699         PrintF("    stop unstop\n");
    700         PrintF("      ignore the stop instruction at the current location\n");
    701         PrintF("      from now on\n");
    702       } else {
    703         PrintF("Unknown command: %s\n", cmd);
    704       }
    705     }
    706   }
    707 
    708   // Add all the breakpoints back to stop execution and enter the debugger
    709   // shell when hit.
    710   RedoBreakpoints();
    711 
    712 #undef COMMAND_SIZE
    713 #undef ARG_SIZE
    714 
    715 #undef STR
    716 #undef XSTR
    717 }
    718 
    719 
    720 static bool ICacheMatch(void* one, void* two) {
    721   DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
    722   DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
    723   return one == two;
    724 }
    725 
    726 
    727 static uint32_t ICacheHash(void* key) {
    728   return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
    729 }
    730 
    731 
    732 static bool AllOnOnePage(uintptr_t start, size_t size) {
    733   intptr_t start_page = (start & ~CachePage::kPageMask);
    734   intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
    735   return start_page == end_page;
    736 }
    737 
    738 
    739 void Simulator::set_last_debugger_input(char* input) {
    740   DeleteArray(last_debugger_input_);
    741   last_debugger_input_ = input;
    742 }
    743 
    744 void Simulator::FlushICache(base::CustomMatcherHashMap* i_cache,
    745                             void* start_addr, size_t size) {
    746   int64_t start = reinterpret_cast<int64_t>(start_addr);
    747   int64_t intra_line = (start & CachePage::kLineMask);
    748   start -= intra_line;
    749   size += intra_line;
    750   size = ((size - 1) | CachePage::kLineMask) + 1;
    751   int offset = (start & CachePage::kPageMask);
    752   while (!AllOnOnePage(start, size - 1)) {
    753     int bytes_to_flush = CachePage::kPageSize - offset;
    754     FlushOnePage(i_cache, start, bytes_to_flush);
    755     start += bytes_to_flush;
    756     size -= bytes_to_flush;
    757     DCHECK_EQ((int64_t)0, start & CachePage::kPageMask);
    758     offset = 0;
    759   }
    760   if (size != 0) {
    761     FlushOnePage(i_cache, start, size);
    762   }
    763 }
    764 
    765 CachePage* Simulator::GetCachePage(base::CustomMatcherHashMap* i_cache,
    766                                    void* page) {
    767   base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page));
    768   if (entry->value == NULL) {
    769     CachePage* new_page = new CachePage();
    770     entry->value = new_page;
    771   }
    772   return reinterpret_cast<CachePage*>(entry->value);
    773 }
    774 
    775 
    776 // Flush from start up to and not including start + size.
    777 void Simulator::FlushOnePage(base::CustomMatcherHashMap* i_cache,
    778                              intptr_t start, size_t size) {
    779   DCHECK(size <= CachePage::kPageSize);
    780   DCHECK(AllOnOnePage(start, size - 1));
    781   DCHECK((start & CachePage::kLineMask) == 0);
    782   DCHECK((size & CachePage::kLineMask) == 0);
    783   void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
    784   int offset = (start & CachePage::kPageMask);
    785   CachePage* cache_page = GetCachePage(i_cache, page);
    786   char* valid_bytemap = cache_page->ValidityByte(offset);
    787   memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
    788 }
    789 
    790 void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
    791                             Instruction* instr) {
    792   int64_t address = reinterpret_cast<int64_t>(instr);
    793   void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
    794   void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
    795   int offset = (address & CachePage::kPageMask);
    796   CachePage* cache_page = GetCachePage(i_cache, page);
    797   char* cache_valid_byte = cache_page->ValidityByte(offset);
    798   bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
    799   char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
    800   if (cache_hit) {
    801     // Check that the data in memory matches the contents of the I-cache.
    802     CHECK_EQ(0, memcmp(reinterpret_cast<void*>(instr),
    803                        cache_page->CachedData(offset),
    804                        Instruction::kInstrSize));
    805   } else {
    806     // Cache miss.  Load memory into the cache.
    807     memcpy(cached_line, line, CachePage::kLineLength);
    808     *cache_valid_byte = CachePage::LINE_VALID;
    809   }
    810 }
    811 
    812 
    813 void Simulator::Initialize(Isolate* isolate) {
    814   if (isolate->simulator_initialized()) return;
    815   isolate->set_simulator_initialized(true);
    816   ::v8::internal::ExternalReference::set_redirector(isolate,
    817                                                     &RedirectExternalReference);
    818 }
    819 
    820 
    821 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
    822   i_cache_ = isolate_->simulator_i_cache();
    823   if (i_cache_ == NULL) {
    824     i_cache_ = new base::CustomMatcherHashMap(&ICacheMatch);
    825     isolate_->set_simulator_i_cache(i_cache_);
    826   }
    827   Initialize(isolate);
    828   // Set up simulator support first. Some of this information is needed to
    829   // setup the architecture state.
    830   stack_size_ = FLAG_sim_stack_size * KB;
    831   stack_ = reinterpret_cast<char*>(malloc(stack_size_));
    832   pc_modified_ = false;
    833   icount_ = 0;
    834   break_count_ = 0;
    835   break_pc_ = NULL;
    836   break_instr_ = 0;
    837 
    838   // Set up architecture state.
    839   // All registers are initialized to zero to start with.
    840   for (int i = 0; i < kNumSimuRegisters; i++) {
    841     registers_[i] = 0;
    842   }
    843   for (int i = 0; i < kNumFPURegisters; i++) {
    844     FPUregisters_[i] = 0;
    845   }
    846 
    847   if (kArchVariant == kMips64r6) {
    848     FCSR_ = kFCSRNaN2008FlagMask;
    849   } else {
    850     FCSR_ = 0;
    851   }
    852 
    853   // The sp is initialized to point to the bottom (high address) of the
    854   // allocated stack area. To be safe in potential stack underflows we leave
    855   // some buffer below.
    856   registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64;
    857   // The ra and pc are initialized to a known bad value that will cause an
    858   // access violation if the simulator ever tries to execute it.
    859   registers_[pc] = bad_ra;
    860   registers_[ra] = bad_ra;
    861 
    862   last_debugger_input_ = NULL;
    863 }
    864 
    865 
    866 Simulator::~Simulator() { free(stack_); }
    867 
    868 
    869 // When the generated code calls an external reference we need to catch that in
    870 // the simulator.  The external reference will be a function compiled for the
    871 // host architecture.  We need to call that function instead of trying to
    872 // execute it with the simulator.  We do that by redirecting the external
    873 // reference to a swi (software-interrupt) instruction that is handled by
    874 // the simulator.  We write the original destination of the jump just at a known
    875 // offset from the swi instruction so the simulator knows what to call.
    876 class Redirection {
    877  public:
    878   Redirection(Isolate* isolate, void* external_function,
    879               ExternalReference::Type type)
    880       : external_function_(external_function),
    881         swi_instruction_(rtCallRedirInstr),
    882         type_(type),
    883         next_(NULL) {
    884     next_ = isolate->simulator_redirection();
    885     Simulator::current(isolate)->
    886         FlushICache(isolate->simulator_i_cache(),
    887                     reinterpret_cast<void*>(&swi_instruction_),
    888                     Instruction::kInstrSize);
    889     isolate->set_simulator_redirection(this);
    890   }
    891 
    892   void* address_of_swi_instruction() {
    893     return reinterpret_cast<void*>(&swi_instruction_);
    894   }
    895 
    896   void* external_function() { return external_function_; }
    897   ExternalReference::Type type() { return type_; }
    898 
    899   static Redirection* Get(Isolate* isolate, void* external_function,
    900                           ExternalReference::Type type) {
    901     Redirection* current = isolate->simulator_redirection();
    902     for (; current != NULL; current = current->next_) {
    903       if (current->external_function_ == external_function) return current;
    904     }
    905     return new Redirection(isolate, external_function, type);
    906   }
    907 
    908   static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
    909     char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
    910     char* addr_of_redirection =
    911         addr_of_swi - offsetof(Redirection, swi_instruction_);
    912     return reinterpret_cast<Redirection*>(addr_of_redirection);
    913   }
    914 
    915   static void* ReverseRedirection(int64_t reg) {
    916     Redirection* redirection = FromSwiInstruction(
    917         reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
    918     return redirection->external_function();
    919   }
    920 
    921   static void DeleteChain(Redirection* redirection) {
    922     while (redirection != nullptr) {
    923       Redirection* next = redirection->next_;
    924       delete redirection;
    925       redirection = next;
    926     }
    927   }
    928 
    929  private:
    930   void* external_function_;
    931   uint32_t swi_instruction_;
    932   ExternalReference::Type type_;
    933   Redirection* next_;
    934 };
    935 
    936 
    937 // static
    938 void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
    939                          Redirection* first) {
    940   Redirection::DeleteChain(first);
    941   if (i_cache != nullptr) {
    942     for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
    943          entry = i_cache->Next(entry)) {
    944       delete static_cast<CachePage*>(entry->value);
    945     }
    946     delete i_cache;
    947   }
    948 }
    949 
    950 
    951 void* Simulator::RedirectExternalReference(Isolate* isolate,
    952                                            void* external_function,
    953                                            ExternalReference::Type type) {
    954   Redirection* redirection = Redirection::Get(isolate, external_function, type);
    955   return redirection->address_of_swi_instruction();
    956 }
    957 
    958 
    959 // Get the active Simulator for the current thread.
    960 Simulator* Simulator::current(Isolate* isolate) {
    961   v8::internal::Isolate::PerIsolateThreadData* isolate_data =
    962        isolate->FindOrAllocatePerThreadDataForThisThread();
    963   DCHECK(isolate_data != NULL);
    964   DCHECK(isolate_data != NULL);
    965 
    966   Simulator* sim = isolate_data->simulator();
    967   if (sim == NULL) {
    968     // TODO(146): delete the simulator object when a thread/isolate goes away.
    969     sim = new Simulator(isolate);
    970     isolate_data->set_simulator(sim);
    971   }
    972   return sim;
    973 }
    974 
    975 
    976 // Sets the register in the architecture state. It will also deal with updating
    977 // Simulator internal state for special registers such as PC.
    978 void Simulator::set_register(int reg, int64_t value) {
    979   DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
    980   if (reg == pc) {
    981     pc_modified_ = true;
    982   }
    983 
    984   // Zero register always holds 0.
    985   registers_[reg] = (reg == 0) ? 0 : value;
    986 }
    987 
    988 
    989 void Simulator::set_dw_register(int reg, const int* dbl) {
    990   DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
    991   registers_[reg] = dbl[1];
    992   registers_[reg] = registers_[reg] << 32;
    993   registers_[reg] += dbl[0];
    994 }
    995 
    996 
    997 void Simulator::set_fpu_register(int fpureg, int64_t value) {
    998   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
    999   FPUregisters_[fpureg] = value;
   1000 }
   1001 
   1002 
   1003 void Simulator::set_fpu_register_word(int fpureg, int32_t value) {
   1004   // Set ONLY lower 32-bits, leaving upper bits untouched.
   1005   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1006   int32_t* pword;
   1007   if (kArchEndian == kLittle) {
   1008     pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]);
   1009   } else {
   1010     pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]) + 1;
   1011   }
   1012   *pword = value;
   1013 }
   1014 
   1015 
   1016 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) {
   1017   // Set ONLY upper 32-bits, leaving lower bits untouched.
   1018   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1019   int32_t* phiword;
   1020   if (kArchEndian == kLittle) {
   1021     phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1;
   1022   } else {
   1023     phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]);
   1024   }
   1025   *phiword = value;
   1026 }
   1027 
   1028 
   1029 void Simulator::set_fpu_register_float(int fpureg, float value) {
   1030   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1031   *bit_cast<float*>(&FPUregisters_[fpureg]) = value;
   1032 }
   1033 
   1034 
   1035 void Simulator::set_fpu_register_double(int fpureg, double value) {
   1036   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1037   *bit_cast<double*>(&FPUregisters_[fpureg]) = value;
   1038 }
   1039 
   1040 
   1041 // Get the register from the architecture state. This function does handle
   1042 // the special case of accessing the PC register.
   1043 int64_t Simulator::get_register(int reg) const {
   1044   DCHECK((reg >= 0) && (reg < kNumSimuRegisters));
   1045   if (reg == 0)
   1046     return 0;
   1047   else
   1048     return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
   1049 }
   1050 
   1051 
   1052 double Simulator::get_double_from_register_pair(int reg) {
   1053   // TODO(plind): bad ABI stuff, refactor or remove.
   1054   DCHECK((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0));
   1055 
   1056   double dm_val = 0.0;
   1057   // Read the bits from the unsigned integer register_[] array
   1058   // into the double precision floating point value and return it.
   1059   char buffer[sizeof(registers_[0])];
   1060   memcpy(buffer, &registers_[reg], sizeof(registers_[0]));
   1061   memcpy(&dm_val, buffer, sizeof(registers_[0]));
   1062   return(dm_val);
   1063 }
   1064 
   1065 
   1066 int64_t Simulator::get_fpu_register(int fpureg) const {
   1067   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1068   return FPUregisters_[fpureg];
   1069 }
   1070 
   1071 
   1072 int32_t Simulator::get_fpu_register_word(int fpureg) const {
   1073   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1074   return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
   1075 }
   1076 
   1077 
   1078 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const {
   1079   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1080   return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
   1081 }
   1082 
   1083 
   1084 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const {
   1085   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1086   return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff);
   1087 }
   1088 
   1089 
   1090 float Simulator::get_fpu_register_float(int fpureg) const {
   1091   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1092   return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg]));
   1093 }
   1094 
   1095 
   1096 double Simulator::get_fpu_register_double(int fpureg) const {
   1097   DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1098   return *bit_cast<double*>(&FPUregisters_[fpureg]);
   1099 }
   1100 
   1101 
   1102 // Runtime FP routines take up to two double arguments and zero
   1103 // or one integer arguments. All are constructed here,
   1104 // from a0-a3 or f12 and f13 (n64), or f14 (O32).
   1105 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
   1106   if (!IsMipsSoftFloatABI) {
   1107     const int fparg2 = 13;
   1108     *x = get_fpu_register_double(12);
   1109     *y = get_fpu_register_double(fparg2);
   1110     *z = static_cast<int32_t>(get_register(a2));
   1111   } else {
   1112   // TODO(plind): bad ABI stuff, refactor or remove.
   1113     // We use a char buffer to get around the strict-aliasing rules which
   1114     // otherwise allow the compiler to optimize away the copy.
   1115     char buffer[sizeof(*x)];
   1116     int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
   1117 
   1118     // Registers a0 and a1 -> x.
   1119     reg_buffer[0] = get_register(a0);
   1120     reg_buffer[1] = get_register(a1);
   1121     memcpy(x, buffer, sizeof(buffer));
   1122     // Registers a2 and a3 -> y.
   1123     reg_buffer[0] = get_register(a2);
   1124     reg_buffer[1] = get_register(a3);
   1125     memcpy(y, buffer, sizeof(buffer));
   1126     // Register 2 -> z.
   1127     reg_buffer[0] = get_register(a2);
   1128     memcpy(z, buffer, sizeof(*z));
   1129   }
   1130 }
   1131 
   1132 
   1133 // The return value is either in v0/v1 or f0.
   1134 void Simulator::SetFpResult(const double& result) {
   1135   if (!IsMipsSoftFloatABI) {
   1136     set_fpu_register_double(0, result);
   1137   } else {
   1138     char buffer[2 * sizeof(registers_[0])];
   1139     int64_t* reg_buffer = reinterpret_cast<int64_t*>(buffer);
   1140     memcpy(buffer, &result, sizeof(buffer));
   1141     // Copy result to v0 and v1.
   1142     set_register(v0, reg_buffer[0]);
   1143     set_register(v1, reg_buffer[1]);
   1144   }
   1145 }
   1146 
   1147 
   1148 // Helper functions for setting and testing the FCSR register's bits.
   1149 void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
   1150   if (value) {
   1151     FCSR_ |= (1 << cc);
   1152   } else {
   1153     FCSR_ &= ~(1 << cc);
   1154   }
   1155 }
   1156 
   1157 
   1158 bool Simulator::test_fcsr_bit(uint32_t cc) {
   1159   return FCSR_ & (1 << cc);
   1160 }
   1161 
   1162 
   1163 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) {
   1164   FCSR_ |= mode & kFPURoundingModeMask;
   1165 }
   1166 
   1167 
   1168 unsigned int Simulator::get_fcsr_rounding_mode() {
   1169   return FCSR_ & kFPURoundingModeMask;
   1170 }
   1171 
   1172 
   1173 // Sets the rounding error codes in FCSR based on the result of the rounding.
   1174 // Returns true if the operation was invalid.
   1175 bool Simulator::set_fcsr_round_error(double original, double rounded) {
   1176   bool ret = false;
   1177   double max_int32 = std::numeric_limits<int32_t>::max();
   1178   double min_int32 = std::numeric_limits<int32_t>::min();
   1179 
   1180   if (!std::isfinite(original) || !std::isfinite(rounded)) {
   1181     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1182     ret = true;
   1183   }
   1184 
   1185   if (original != rounded) {
   1186     set_fcsr_bit(kFCSRInexactFlagBit, true);
   1187   }
   1188 
   1189   if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
   1190     set_fcsr_bit(kFCSRUnderflowFlagBit, true);
   1191     ret = true;
   1192   }
   1193 
   1194   if (rounded > max_int32 || rounded < min_int32) {
   1195     set_fcsr_bit(kFCSROverflowFlagBit, true);
   1196     // The reference is not really clear but it seems this is required:
   1197     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1198     ret = true;
   1199   }
   1200 
   1201   return ret;
   1202 }
   1203 
   1204 
   1205 // Sets the rounding error codes in FCSR based on the result of the rounding.
   1206 // Returns true if the operation was invalid.
   1207 bool Simulator::set_fcsr_round64_error(double original, double rounded) {
   1208   bool ret = false;
   1209   // The value of INT64_MAX (2^63-1) can't be represented as double exactly,
   1210   // loading the most accurate representation into max_int64, which is 2^63.
   1211   double max_int64 = std::numeric_limits<int64_t>::max();
   1212   double min_int64 = std::numeric_limits<int64_t>::min();
   1213 
   1214   if (!std::isfinite(original) || !std::isfinite(rounded)) {
   1215     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1216     ret = true;
   1217   }
   1218 
   1219   if (original != rounded) {
   1220     set_fcsr_bit(kFCSRInexactFlagBit, true);
   1221   }
   1222 
   1223   if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
   1224     set_fcsr_bit(kFCSRUnderflowFlagBit, true);
   1225     ret = true;
   1226   }
   1227 
   1228   if (rounded >= max_int64 || rounded < min_int64) {
   1229     set_fcsr_bit(kFCSROverflowFlagBit, true);
   1230     // The reference is not really clear but it seems this is required:
   1231     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1232     ret = true;
   1233   }
   1234 
   1235   return ret;
   1236 }
   1237 
   1238 
   1239 // Sets the rounding error codes in FCSR based on the result of the rounding.
   1240 // Returns true if the operation was invalid.
   1241 bool Simulator::set_fcsr_round_error(float original, float rounded) {
   1242   bool ret = false;
   1243   double max_int32 = std::numeric_limits<int32_t>::max();
   1244   double min_int32 = std::numeric_limits<int32_t>::min();
   1245 
   1246   if (!std::isfinite(original) || !std::isfinite(rounded)) {
   1247     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1248     ret = true;
   1249   }
   1250 
   1251   if (original != rounded) {
   1252     set_fcsr_bit(kFCSRInexactFlagBit, true);
   1253   }
   1254 
   1255   if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) {
   1256     set_fcsr_bit(kFCSRUnderflowFlagBit, true);
   1257     ret = true;
   1258   }
   1259 
   1260   if (rounded > max_int32 || rounded < min_int32) {
   1261     set_fcsr_bit(kFCSROverflowFlagBit, true);
   1262     // The reference is not really clear but it seems this is required:
   1263     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1264     ret = true;
   1265   }
   1266 
   1267   return ret;
   1268 }
   1269 
   1270 void Simulator::set_fpu_register_word_invalid_result(float original,
   1271                                                      float rounded) {
   1272   if (FCSR_ & kFCSRNaN2008FlagMask) {
   1273     double max_int32 = std::numeric_limits<int32_t>::max();
   1274     double min_int32 = std::numeric_limits<int32_t>::min();
   1275     if (std::isnan(original)) {
   1276       set_fpu_register_word(fd_reg(), 0);
   1277     } else if (rounded > max_int32) {
   1278       set_fpu_register_word(fd_reg(), kFPUInvalidResult);
   1279     } else if (rounded < min_int32) {
   1280       set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
   1281     } else {
   1282       UNREACHABLE();
   1283     }
   1284   } else {
   1285     set_fpu_register_word(fd_reg(), kFPUInvalidResult);
   1286   }
   1287 }
   1288 
   1289 
   1290 void Simulator::set_fpu_register_invalid_result(float original, float rounded) {
   1291   if (FCSR_ & kFCSRNaN2008FlagMask) {
   1292     double max_int32 = std::numeric_limits<int32_t>::max();
   1293     double min_int32 = std::numeric_limits<int32_t>::min();
   1294     if (std::isnan(original)) {
   1295       set_fpu_register(fd_reg(), 0);
   1296     } else if (rounded > max_int32) {
   1297       set_fpu_register(fd_reg(), kFPUInvalidResult);
   1298     } else if (rounded < min_int32) {
   1299       set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
   1300     } else {
   1301       UNREACHABLE();
   1302     }
   1303   } else {
   1304     set_fpu_register(fd_reg(), kFPUInvalidResult);
   1305   }
   1306 }
   1307 
   1308 
   1309 void Simulator::set_fpu_register_invalid_result64(float original,
   1310                                                   float rounded) {
   1311   if (FCSR_ & kFCSRNaN2008FlagMask) {
   1312     // The value of INT64_MAX (2^63-1) can't be represented as double exactly,
   1313     // loading the most accurate representation into max_int64, which is 2^63.
   1314     double max_int64 = std::numeric_limits<int64_t>::max();
   1315     double min_int64 = std::numeric_limits<int64_t>::min();
   1316     if (std::isnan(original)) {
   1317       set_fpu_register(fd_reg(), 0);
   1318     } else if (rounded >= max_int64) {
   1319       set_fpu_register(fd_reg(), kFPU64InvalidResult);
   1320     } else if (rounded < min_int64) {
   1321       set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
   1322     } else {
   1323       UNREACHABLE();
   1324     }
   1325   } else {
   1326     set_fpu_register(fd_reg(), kFPU64InvalidResult);
   1327   }
   1328 }
   1329 
   1330 
   1331 void Simulator::set_fpu_register_word_invalid_result(double original,
   1332                                                      double rounded) {
   1333   if (FCSR_ & kFCSRNaN2008FlagMask) {
   1334     double max_int32 = std::numeric_limits<int32_t>::max();
   1335     double min_int32 = std::numeric_limits<int32_t>::min();
   1336     if (std::isnan(original)) {
   1337       set_fpu_register_word(fd_reg(), 0);
   1338     } else if (rounded > max_int32) {
   1339       set_fpu_register_word(fd_reg(), kFPUInvalidResult);
   1340     } else if (rounded < min_int32) {
   1341       set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
   1342     } else {
   1343       UNREACHABLE();
   1344     }
   1345   } else {
   1346     set_fpu_register_word(fd_reg(), kFPUInvalidResult);
   1347   }
   1348 }
   1349 
   1350 
   1351 void Simulator::set_fpu_register_invalid_result(double original,
   1352                                                 double rounded) {
   1353   if (FCSR_ & kFCSRNaN2008FlagMask) {
   1354     double max_int32 = std::numeric_limits<int32_t>::max();
   1355     double min_int32 = std::numeric_limits<int32_t>::min();
   1356     if (std::isnan(original)) {
   1357       set_fpu_register(fd_reg(), 0);
   1358     } else if (rounded > max_int32) {
   1359       set_fpu_register(fd_reg(), kFPUInvalidResult);
   1360     } else if (rounded < min_int32) {
   1361       set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
   1362     } else {
   1363       UNREACHABLE();
   1364     }
   1365   } else {
   1366     set_fpu_register(fd_reg(), kFPUInvalidResult);
   1367   }
   1368 }
   1369 
   1370 
   1371 void Simulator::set_fpu_register_invalid_result64(double original,
   1372                                                   double rounded) {
   1373   if (FCSR_ & kFCSRNaN2008FlagMask) {
   1374     // The value of INT64_MAX (2^63-1) can't be represented as double exactly,
   1375     // loading the most accurate representation into max_int64, which is 2^63.
   1376     double max_int64 = std::numeric_limits<int64_t>::max();
   1377     double min_int64 = std::numeric_limits<int64_t>::min();
   1378     if (std::isnan(original)) {
   1379       set_fpu_register(fd_reg(), 0);
   1380     } else if (rounded >= max_int64) {
   1381       set_fpu_register(fd_reg(), kFPU64InvalidResult);
   1382     } else if (rounded < min_int64) {
   1383       set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
   1384     } else {
   1385       UNREACHABLE();
   1386     }
   1387   } else {
   1388     set_fpu_register(fd_reg(), kFPU64InvalidResult);
   1389   }
   1390 }
   1391 
   1392 
   1393 // Sets the rounding error codes in FCSR based on the result of the rounding.
   1394 // Returns true if the operation was invalid.
   1395 bool Simulator::set_fcsr_round64_error(float original, float rounded) {
   1396   bool ret = false;
   1397   // The value of INT64_MAX (2^63-1) can't be represented as double exactly,
   1398   // loading the most accurate representation into max_int64, which is 2^63.
   1399   double max_int64 = std::numeric_limits<int64_t>::max();
   1400   double min_int64 = std::numeric_limits<int64_t>::min();
   1401 
   1402   if (!std::isfinite(original) || !std::isfinite(rounded)) {
   1403     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1404     ret = true;
   1405   }
   1406 
   1407   if (original != rounded) {
   1408     set_fcsr_bit(kFCSRInexactFlagBit, true);
   1409   }
   1410 
   1411   if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) {
   1412     set_fcsr_bit(kFCSRUnderflowFlagBit, true);
   1413     ret = true;
   1414   }
   1415 
   1416   if (rounded >= max_int64 || rounded < min_int64) {
   1417     set_fcsr_bit(kFCSROverflowFlagBit, true);
   1418     // The reference is not really clear but it seems this is required:
   1419     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1420     ret = true;
   1421   }
   1422 
   1423   return ret;
   1424 }
   1425 
   1426 
   1427 // For cvt instructions only
   1428 void Simulator::round_according_to_fcsr(double toRound, double& rounded,
   1429                                         int32_t& rounded_int, double fs) {
   1430   // 0 RN (round to nearest): Round a result to the nearest
   1431   // representable value; if the result is exactly halfway between
   1432   // two representable values, round to zero. Behave like round_w_d.
   1433 
   1434   // 1 RZ (round toward zero): Round a result to the closest
   1435   // representable value whose absolute value is less than or
   1436   // equal to the infinitely accurate result. Behave like trunc_w_d.
   1437 
   1438   // 2 RP (round up, or toward +infinity): Round a result to the
   1439   // next representable value up. Behave like ceil_w_d.
   1440 
   1441   // 3 RN (round down, or toward infinity): Round a result to
   1442   // the next representable value down. Behave like floor_w_d.
   1443   switch (FCSR_ & 3) {
   1444     case kRoundToNearest:
   1445       rounded = std::floor(fs + 0.5);
   1446       rounded_int = static_cast<int32_t>(rounded);
   1447       if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
   1448         // If the number is halfway between two integers,
   1449         // round to the even one.
   1450         rounded_int--;
   1451       }
   1452       break;
   1453     case kRoundToZero:
   1454       rounded = trunc(fs);
   1455       rounded_int = static_cast<int32_t>(rounded);
   1456       break;
   1457     case kRoundToPlusInf:
   1458       rounded = std::ceil(fs);
   1459       rounded_int = static_cast<int32_t>(rounded);
   1460       break;
   1461     case kRoundToMinusInf:
   1462       rounded = std::floor(fs);
   1463       rounded_int = static_cast<int32_t>(rounded);
   1464       break;
   1465   }
   1466 }
   1467 
   1468 
   1469 void Simulator::round64_according_to_fcsr(double toRound, double& rounded,
   1470                                           int64_t& rounded_int, double fs) {
   1471   // 0 RN (round to nearest): Round a result to the nearest
   1472   // representable value; if the result is exactly halfway between
   1473   // two representable values, round to zero. Behave like round_w_d.
   1474 
   1475   // 1 RZ (round toward zero): Round a result to the closest
   1476   // representable value whose absolute value is less than or.
   1477   // equal to the infinitely accurate result. Behave like trunc_w_d.
   1478 
   1479   // 2 RP (round up, or toward +infinity): Round a result to the
   1480   // next representable value up. Behave like ceil_w_d.
   1481 
   1482   // 3 RN (round down, or toward infinity): Round a result to
   1483   // the next representable value down. Behave like floor_w_d.
   1484   switch (FCSR_ & 3) {
   1485     case kRoundToNearest:
   1486       rounded = std::floor(fs + 0.5);
   1487       rounded_int = static_cast<int64_t>(rounded);
   1488       if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
   1489         // If the number is halfway between two integers,
   1490         // round to the even one.
   1491         rounded_int--;
   1492       }
   1493       break;
   1494     case kRoundToZero:
   1495       rounded = trunc(fs);
   1496       rounded_int = static_cast<int64_t>(rounded);
   1497       break;
   1498     case kRoundToPlusInf:
   1499       rounded = std::ceil(fs);
   1500       rounded_int = static_cast<int64_t>(rounded);
   1501       break;
   1502     case kRoundToMinusInf:
   1503       rounded = std::floor(fs);
   1504       rounded_int = static_cast<int64_t>(rounded);
   1505       break;
   1506   }
   1507 }
   1508 
   1509 
   1510 // for cvt instructions only
   1511 void Simulator::round_according_to_fcsr(float toRound, float& rounded,
   1512                                         int32_t& rounded_int, float fs) {
   1513   // 0 RN (round to nearest): Round a result to the nearest
   1514   // representable value; if the result is exactly halfway between
   1515   // two representable values, round to zero. Behave like round_w_d.
   1516 
   1517   // 1 RZ (round toward zero): Round a result to the closest
   1518   // representable value whose absolute value is less than or
   1519   // equal to the infinitely accurate result. Behave like trunc_w_d.
   1520 
   1521   // 2 RP (round up, or toward +infinity): Round a result to the
   1522   // next representable value up. Behave like ceil_w_d.
   1523 
   1524   // 3 RN (round down, or toward infinity): Round a result to
   1525   // the next representable value down. Behave like floor_w_d.
   1526   switch (FCSR_ & 3) {
   1527     case kRoundToNearest:
   1528       rounded = std::floor(fs + 0.5);
   1529       rounded_int = static_cast<int32_t>(rounded);
   1530       if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
   1531         // If the number is halfway between two integers,
   1532         // round to the even one.
   1533         rounded_int--;
   1534       }
   1535       break;
   1536     case kRoundToZero:
   1537       rounded = trunc(fs);
   1538       rounded_int = static_cast<int32_t>(rounded);
   1539       break;
   1540     case kRoundToPlusInf:
   1541       rounded = std::ceil(fs);
   1542       rounded_int = static_cast<int32_t>(rounded);
   1543       break;
   1544     case kRoundToMinusInf:
   1545       rounded = std::floor(fs);
   1546       rounded_int = static_cast<int32_t>(rounded);
   1547       break;
   1548   }
   1549 }
   1550 
   1551 
   1552 void Simulator::round64_according_to_fcsr(float toRound, float& rounded,
   1553                                           int64_t& rounded_int, float fs) {
   1554   // 0 RN (round to nearest): Round a result to the nearest
   1555   // representable value; if the result is exactly halfway between
   1556   // two representable values, round to zero. Behave like round_w_d.
   1557 
   1558   // 1 RZ (round toward zero): Round a result to the closest
   1559   // representable value whose absolute value is less than or.
   1560   // equal to the infinitely accurate result. Behave like trunc_w_d.
   1561 
   1562   // 2 RP (round up, or toward +infinity): Round a result to the
   1563   // next representable value up. Behave like ceil_w_d.
   1564 
   1565   // 3 RN (round down, or toward infinity): Round a result to
   1566   // the next representable value down. Behave like floor_w_d.
   1567   switch (FCSR_ & 3) {
   1568     case kRoundToNearest:
   1569       rounded = std::floor(fs + 0.5);
   1570       rounded_int = static_cast<int64_t>(rounded);
   1571       if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
   1572         // If the number is halfway between two integers,
   1573         // round to the even one.
   1574         rounded_int--;
   1575       }
   1576       break;
   1577     case kRoundToZero:
   1578       rounded = trunc(fs);
   1579       rounded_int = static_cast<int64_t>(rounded);
   1580       break;
   1581     case kRoundToPlusInf:
   1582       rounded = std::ceil(fs);
   1583       rounded_int = static_cast<int64_t>(rounded);
   1584       break;
   1585     case kRoundToMinusInf:
   1586       rounded = std::floor(fs);
   1587       rounded_int = static_cast<int64_t>(rounded);
   1588       break;
   1589   }
   1590 }
   1591 
   1592 
   1593 // Raw access to the PC register.
   1594 void Simulator::set_pc(int64_t value) {
   1595   pc_modified_ = true;
   1596   registers_[pc] = value;
   1597 }
   1598 
   1599 
   1600 bool Simulator::has_bad_pc() const {
   1601   return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc));
   1602 }
   1603 
   1604 
   1605 // Raw access to the PC register without the special adjustment when reading.
   1606 int64_t Simulator::get_pc() const {
   1607   return registers_[pc];
   1608 }
   1609 
   1610 
   1611 // The MIPS cannot do unaligned reads and writes.  On some MIPS platforms an
   1612 // interrupt is caused.  On others it does a funky rotation thing.  For now we
   1613 // simply disallow unaligned reads, but at some point we may want to move to
   1614 // emulating the rotate behaviour.  Note that simulator runs have the runtime
   1615 // system running directly on the host system and only generated code is
   1616 // executed in the simulator.  Since the host is typically IA32 we will not
   1617 // get the correct MIPS-like behaviour on unaligned accesses.
   1618 
   1619 // TODO(plind): refactor this messy debug code when we do unaligned access.
   1620 void Simulator::DieOrDebug() {
   1621   if (1) {  // Flag for this was removed.
   1622     MipsDebugger dbg(this);
   1623     dbg.Debug();
   1624   } else {
   1625     base::OS::Abort();
   1626   }
   1627 }
   1628 
   1629 
   1630 void Simulator::TraceRegWr(int64_t value) {
   1631   if (::v8::internal::FLAG_trace_sim) {
   1632     SNPrintF(trace_buf_, "%016" PRIx64 " ", value);
   1633   }
   1634 }
   1635 
   1636 
   1637 // TODO(plind): consider making icount_ printing a flag option.
   1638 void Simulator::TraceMemRd(int64_t addr, int64_t value) {
   1639   if (::v8::internal::FLAG_trace_sim) {
   1640     SNPrintF(trace_buf_,
   1641              "%016" PRIx64 "  <-- [%016" PRIx64 " ]    (%" PRId64 " )", value,
   1642              addr, icount_);
   1643   }
   1644 }
   1645 
   1646 
   1647 void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) {
   1648   if (::v8::internal::FLAG_trace_sim) {
   1649     switch (t) {
   1650       case BYTE:
   1651         SNPrintF(trace_buf_, "               %02x --> [%016" PRIx64 " ]",
   1652                  static_cast<int8_t>(value), addr);
   1653         break;
   1654       case HALF:
   1655         SNPrintF(trace_buf_, "            %04x --> [%016" PRIx64 " ]",
   1656                  static_cast<int16_t>(value), addr);
   1657         break;
   1658       case WORD:
   1659         SNPrintF(trace_buf_, "        %08x --> [%016" PRIx64 " ]",
   1660                  static_cast<int32_t>(value), addr);
   1661         break;
   1662       case DWORD:
   1663         SNPrintF(trace_buf_,
   1664                  "%016" PRIx64 "  --> [%016" PRIx64 " ]    (%" PRId64 " )",
   1665                  value, addr, icount_);
   1666         break;
   1667     }
   1668   }
   1669 }
   1670 
   1671 
   1672 // TODO(plind): sign-extend and zero-extend not implmented properly
   1673 // on all the ReadXX functions, I don't think re-interpret cast does it.
   1674 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) {
   1675   if (addr >=0 && addr < 0x400) {
   1676     // This has to be a NULL-dereference, drop into debugger.
   1677     PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR
   1678            " \n",
   1679            addr, reinterpret_cast<intptr_t>(instr));
   1680     DieOrDebug();
   1681   }
   1682   if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) {
   1683     int32_t* ptr = reinterpret_cast<int32_t*>(addr);
   1684     TraceMemRd(addr, static_cast<int64_t>(*ptr));
   1685     return *ptr;
   1686   }
   1687   PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr,
   1688          reinterpret_cast<intptr_t>(instr));
   1689   DieOrDebug();
   1690   return 0;
   1691 }
   1692 
   1693 
   1694 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) {
   1695   if (addr >=0 && addr < 0x400) {
   1696     // This has to be a NULL-dereference, drop into debugger.
   1697     PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR
   1698            " \n",
   1699            addr, reinterpret_cast<intptr_t>(instr));
   1700     DieOrDebug();
   1701   }
   1702   if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) {
   1703     uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
   1704     TraceMemRd(addr, static_cast<int64_t>(*ptr));
   1705     return *ptr;
   1706   }
   1707   PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr,
   1708          reinterpret_cast<intptr_t>(instr));
   1709   DieOrDebug();
   1710   return 0;
   1711 }
   1712 
   1713 
   1714 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) {
   1715   if (addr >= 0 && addr < 0x400) {
   1716     // This has to be a NULL-dereference, drop into debugger.
   1717     PrintF("Memory write to bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR
   1718            " \n",
   1719            addr, reinterpret_cast<intptr_t>(instr));
   1720     DieOrDebug();
   1721   }
   1722   if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) {
   1723     TraceMemWr(addr, value, WORD);
   1724     int* ptr = reinterpret_cast<int*>(addr);
   1725     *ptr = value;
   1726     return;
   1727   }
   1728   PrintF("Unaligned write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr,
   1729          reinterpret_cast<intptr_t>(instr));
   1730   DieOrDebug();
   1731 }
   1732 
   1733 
   1734 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) {
   1735   if (addr >=0 && addr < 0x400) {
   1736     // This has to be a NULL-dereference, drop into debugger.
   1737     PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR
   1738            " \n",
   1739            addr, reinterpret_cast<intptr_t>(instr));
   1740     DieOrDebug();
   1741   }
   1742   if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) {
   1743     int64_t* ptr = reinterpret_cast<int64_t*>(addr);
   1744     TraceMemRd(addr, *ptr);
   1745     return *ptr;
   1746   }
   1747   PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr,
   1748          reinterpret_cast<intptr_t>(instr));
   1749   DieOrDebug();
   1750   return 0;
   1751 }
   1752 
   1753 
   1754 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) {
   1755   if (addr >= 0 && addr < 0x400) {
   1756     // This has to be a NULL-dereference, drop into debugger.
   1757     PrintF("Memory write to bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR
   1758            "\n",
   1759            addr, reinterpret_cast<intptr_t>(instr));
   1760     DieOrDebug();
   1761   }
   1762   if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) {
   1763     TraceMemWr(addr, value, DWORD);
   1764     int64_t* ptr = reinterpret_cast<int64_t*>(addr);
   1765     *ptr = value;
   1766     return;
   1767   }
   1768   PrintF("Unaligned write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr,
   1769          reinterpret_cast<intptr_t>(instr));
   1770   DieOrDebug();
   1771 }
   1772 
   1773 
   1774 double Simulator::ReadD(int64_t addr, Instruction* instr) {
   1775   if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) {
   1776     double* ptr = reinterpret_cast<double*>(addr);
   1777     return *ptr;
   1778   }
   1779   PrintF("Unaligned (double) read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n",
   1780          addr, reinterpret_cast<intptr_t>(instr));
   1781   base::OS::Abort();
   1782   return 0;
   1783 }
   1784 
   1785 
   1786 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) {
   1787   if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) {
   1788     double* ptr = reinterpret_cast<double*>(addr);
   1789     *ptr = value;
   1790     return;
   1791   }
   1792   PrintF("Unaligned (double) write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR
   1793          "\n",
   1794          addr, reinterpret_cast<intptr_t>(instr));
   1795   DieOrDebug();
   1796 }
   1797 
   1798 
   1799 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) {
   1800   if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
   1801     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1802     TraceMemRd(addr, static_cast<int64_t>(*ptr));
   1803     return *ptr;
   1804   }
   1805   PrintF("Unaligned unsigned halfword read at 0x%08" PRIx64
   1806          " , pc=0x%08" V8PRIxPTR "\n",
   1807          addr, reinterpret_cast<intptr_t>(instr));
   1808   DieOrDebug();
   1809   return 0;
   1810 }
   1811 
   1812 
   1813 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) {
   1814   if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
   1815     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1816     TraceMemRd(addr, static_cast<int64_t>(*ptr));
   1817     return *ptr;
   1818   }
   1819   PrintF("Unaligned signed halfword read at 0x%08" PRIx64
   1820          " , pc=0x%08" V8PRIxPTR "\n",
   1821          addr, reinterpret_cast<intptr_t>(instr));
   1822   DieOrDebug();
   1823   return 0;
   1824 }
   1825 
   1826 
   1827 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) {
   1828   if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
   1829     TraceMemWr(addr, value, HALF);
   1830     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1831     *ptr = value;
   1832     return;
   1833   }
   1834   PrintF("Unaligned unsigned halfword write at 0x%08" PRIx64
   1835          " , pc=0x%08" V8PRIxPTR "\n",
   1836          addr, reinterpret_cast<intptr_t>(instr));
   1837   DieOrDebug();
   1838 }
   1839 
   1840 
   1841 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) {
   1842   if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
   1843     TraceMemWr(addr, value, HALF);
   1844     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1845     *ptr = value;
   1846     return;
   1847   }
   1848   PrintF("Unaligned halfword write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR
   1849          "\n",
   1850          addr, reinterpret_cast<intptr_t>(instr));
   1851   DieOrDebug();
   1852 }
   1853 
   1854 
   1855 uint32_t Simulator::ReadBU(int64_t addr) {
   1856   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1857   TraceMemRd(addr, static_cast<int64_t>(*ptr));
   1858   return *ptr & 0xff;
   1859 }
   1860 
   1861 
   1862 int32_t Simulator::ReadB(int64_t addr) {
   1863   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1864   TraceMemRd(addr, static_cast<int64_t>(*ptr));
   1865   return *ptr;
   1866 }
   1867 
   1868 
   1869 void Simulator::WriteB(int64_t addr, uint8_t value) {
   1870   TraceMemWr(addr, value, BYTE);
   1871   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1872   *ptr = value;
   1873 }
   1874 
   1875 
   1876 void Simulator::WriteB(int64_t addr, int8_t value) {
   1877   TraceMemWr(addr, value, BYTE);
   1878   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1879   *ptr = value;
   1880 }
   1881 
   1882 
   1883 // Returns the limit of the stack area to enable checking for stack overflows.
   1884 uintptr_t Simulator::StackLimit(uintptr_t c_limit) const {
   1885   // The simulator uses a separate JS stack. If we have exhausted the C stack,
   1886   // we also drop down the JS limit to reflect the exhaustion on the JS stack.
   1887   if (GetCurrentStackPosition() < c_limit) {
   1888     return reinterpret_cast<uintptr_t>(get_sp());
   1889   }
   1890 
   1891   // Otherwise the limit is the JS stack. Leave a safety margin of 1024 bytes
   1892   // to prevent overrunning the stack when pushing values.
   1893   return reinterpret_cast<uintptr_t>(stack_) + 1024;
   1894 }
   1895 
   1896 
   1897 // Unsupported instructions use Format to print an error and stop execution.
   1898 void Simulator::Format(Instruction* instr, const char* format) {
   1899   PrintF("Simulator found unsupported instruction:\n 0x%08" PRIxPTR " : %s\n",
   1900          reinterpret_cast<intptr_t>(instr), format);
   1901   UNIMPLEMENTED_MIPS();
   1902 }
   1903 
   1904 
   1905 // Calls into the V8 runtime are based on this very simple interface.
   1906 // Note: To be able to return two values from some calls the code in runtime.cc
   1907 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
   1908 // 64-bit value. With the code below we assume that all runtime calls return
   1909 // 64 bits of result. If they don't, the v1 result register contains a bogus
   1910 // value, which is fine because it is caller-saved.
   1911 
   1912 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
   1913                                         int64_t arg1,
   1914                                         int64_t arg2,
   1915                                         int64_t arg3,
   1916                                         int64_t arg4,
   1917                                         int64_t arg5);
   1918 
   1919 typedef ObjectTriple (*SimulatorRuntimeTripleCall)(int64_t arg0, int64_t arg1,
   1920                                                    int64_t arg2, int64_t arg3,
   1921                                                    int64_t arg4);
   1922 
   1923 // These prototypes handle the four types of FP calls.
   1924 typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
   1925 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
   1926 typedef double (*SimulatorRuntimeFPCall)(double darg0);
   1927 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
   1928 
   1929 // This signature supports direct call in to API function native callback
   1930 // (refer to InvocationCallback in v8.h).
   1931 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
   1932 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);
   1933 
   1934 // This signature supports direct call to accessor getter callback.
   1935 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
   1936 typedef void (*SimulatorRuntimeProfilingGetterCall)(
   1937     int64_t arg0, int64_t arg1, void* arg2);
   1938 
   1939 // Software interrupt instructions are used by the simulator to call into the
   1940 // C-based V8 runtime. They are also used for debugging with simulator.
   1941 void Simulator::SoftwareInterrupt() {
   1942   // There are several instructions that could get us here,
   1943   // the break_ instruction, or several variants of traps. All
   1944   // Are "SPECIAL" class opcode, and are distinuished by function.
   1945   int32_t func = instr_.FunctionFieldRaw();
   1946   uint32_t code = (func == BREAK) ? instr_.Bits(25, 6) : -1;
   1947   // We first check if we met a call_rt_redirected.
   1948   if (instr_.InstructionBits() == rtCallRedirInstr) {
   1949     Redirection* redirection = Redirection::FromSwiInstruction(instr_.instr());
   1950     int64_t arg0 = get_register(a0);
   1951     int64_t arg1 = get_register(a1);
   1952     int64_t arg2 = get_register(a2);
   1953     int64_t arg3 = get_register(a3);
   1954     int64_t arg4, arg5;
   1955 
   1956     arg4 = get_register(a4);  // Abi n64 register a4.
   1957     arg5 = get_register(a5);  // Abi n64 register a5.
   1958 
   1959     bool fp_call =
   1960          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
   1961          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
   1962          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
   1963          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
   1964 
   1965     if (!IsMipsSoftFloatABI) {
   1966       // With the hard floating point calling convention, double
   1967       // arguments are passed in FPU registers. Fetch the arguments
   1968       // from there and call the builtin using soft floating point
   1969       // convention.
   1970       switch (redirection->type()) {
   1971       case ExternalReference::BUILTIN_FP_FP_CALL:
   1972       case ExternalReference::BUILTIN_COMPARE_CALL:
   1973         arg0 = get_fpu_register(f12);
   1974         arg1 = get_fpu_register(f13);
   1975         arg2 = get_fpu_register(f14);
   1976         arg3 = get_fpu_register(f15);
   1977         break;
   1978       case ExternalReference::BUILTIN_FP_CALL:
   1979         arg0 = get_fpu_register(f12);
   1980         arg1 = get_fpu_register(f13);
   1981         break;
   1982       case ExternalReference::BUILTIN_FP_INT_CALL:
   1983         arg0 = get_fpu_register(f12);
   1984         arg1 = get_fpu_register(f13);
   1985         arg2 = get_register(a2);
   1986         break;
   1987       default:
   1988         break;
   1989       }
   1990     }
   1991 
   1992     // This is dodgy but it works because the C entry stubs are never moved.
   1993     // See comment in codegen-arm.cc and bug 1242173.
   1994     int64_t saved_ra = get_register(ra);
   1995 
   1996     intptr_t external =
   1997           reinterpret_cast<intptr_t>(redirection->external_function());
   1998 
   1999     // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
   2000     // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
   2001     // simulator. Soft-float has additional abstraction of ExternalReference,
   2002     // to support serialization.
   2003     if (fp_call) {
   2004       double dval0, dval1;  // one or two double parameters
   2005       int32_t ival;         // zero or one integer parameters
   2006       int64_t iresult = 0;  // integer return value
   2007       double dresult = 0;   // double return value
   2008       GetFpArgs(&dval0, &dval1, &ival);
   2009       SimulatorRuntimeCall generic_target =
   2010           reinterpret_cast<SimulatorRuntimeCall>(external);
   2011       if (::v8::internal::FLAG_trace_sim) {
   2012         switch (redirection->type()) {
   2013           case ExternalReference::BUILTIN_FP_FP_CALL:
   2014           case ExternalReference::BUILTIN_COMPARE_CALL:
   2015             PrintF("Call to host function at %p with args %f, %f",
   2016                    static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
   2017                    dval1);
   2018             break;
   2019           case ExternalReference::BUILTIN_FP_CALL:
   2020             PrintF("Call to host function at %p with arg %f",
   2021                    static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0);
   2022             break;
   2023           case ExternalReference::BUILTIN_FP_INT_CALL:
   2024             PrintF("Call to host function at %p with args %f, %d",
   2025                    static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
   2026                    ival);
   2027             break;
   2028           default:
   2029             UNREACHABLE();
   2030             break;
   2031         }
   2032       }
   2033       switch (redirection->type()) {
   2034       case ExternalReference::BUILTIN_COMPARE_CALL: {
   2035         SimulatorRuntimeCompareCall target =
   2036           reinterpret_cast<SimulatorRuntimeCompareCall>(external);
   2037         iresult = target(dval0, dval1);
   2038         set_register(v0, static_cast<int64_t>(iresult));
   2039       //  set_register(v1, static_cast<int64_t>(iresult >> 32));
   2040         break;
   2041       }
   2042       case ExternalReference::BUILTIN_FP_FP_CALL: {
   2043         SimulatorRuntimeFPFPCall target =
   2044           reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
   2045         dresult = target(dval0, dval1);
   2046         SetFpResult(dresult);
   2047         break;
   2048       }
   2049       case ExternalReference::BUILTIN_FP_CALL: {
   2050         SimulatorRuntimeFPCall target =
   2051           reinterpret_cast<SimulatorRuntimeFPCall>(external);
   2052         dresult = target(dval0);
   2053         SetFpResult(dresult);
   2054         break;
   2055       }
   2056       case ExternalReference::BUILTIN_FP_INT_CALL: {
   2057         SimulatorRuntimeFPIntCall target =
   2058           reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
   2059         dresult = target(dval0, ival);
   2060         SetFpResult(dresult);
   2061         break;
   2062       }
   2063       default:
   2064         UNREACHABLE();
   2065         break;
   2066       }
   2067       if (::v8::internal::FLAG_trace_sim) {
   2068         switch (redirection->type()) {
   2069         case ExternalReference::BUILTIN_COMPARE_CALL:
   2070           PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
   2071           break;
   2072         case ExternalReference::BUILTIN_FP_FP_CALL:
   2073         case ExternalReference::BUILTIN_FP_CALL:
   2074         case ExternalReference::BUILTIN_FP_INT_CALL:
   2075           PrintF("Returned %f\n", dresult);
   2076           break;
   2077         default:
   2078           UNREACHABLE();
   2079           break;
   2080         }
   2081       }
   2082     } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
   2083       if (::v8::internal::FLAG_trace_sim) {
   2084         PrintF("Call to host function at %p args %08" PRIx64 " \n",
   2085                reinterpret_cast<void*>(external), arg0);
   2086       }
   2087       SimulatorRuntimeDirectApiCall target =
   2088           reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
   2089       target(arg0);
   2090     } else if (
   2091         redirection->type() == ExternalReference::PROFILING_API_CALL) {
   2092       if (::v8::internal::FLAG_trace_sim) {
   2093         PrintF("Call to host function at %p args %08" PRIx64 "  %08" PRIx64
   2094                " \n",
   2095                reinterpret_cast<void*>(external), arg0, arg1);
   2096       }
   2097       SimulatorRuntimeProfilingApiCall target =
   2098           reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
   2099       target(arg0, Redirection::ReverseRedirection(arg1));
   2100     } else if (
   2101         redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
   2102       if (::v8::internal::FLAG_trace_sim) {
   2103         PrintF("Call to host function at %p args %08" PRIx64 "  %08" PRIx64
   2104                " \n",
   2105                reinterpret_cast<void*>(external), arg0, arg1);
   2106       }
   2107       SimulatorRuntimeDirectGetterCall target =
   2108           reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
   2109       target(arg0, arg1);
   2110     } else if (
   2111         redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
   2112       if (::v8::internal::FLAG_trace_sim) {
   2113         PrintF("Call to host function at %p args %08" PRIx64 "  %08" PRIx64
   2114                "  %08" PRIx64 " \n",
   2115                reinterpret_cast<void*>(external), arg0, arg1, arg2);
   2116       }
   2117       SimulatorRuntimeProfilingGetterCall target =
   2118           reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
   2119       target(arg0, arg1, Redirection::ReverseRedirection(arg2));
   2120     } else if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE) {
   2121       // builtin call returning ObjectTriple.
   2122       SimulatorRuntimeTripleCall target =
   2123           reinterpret_cast<SimulatorRuntimeTripleCall>(external);
   2124       if (::v8::internal::FLAG_trace_sim) {
   2125         PrintF(
   2126             "Call to host triple returning runtime function %p "
   2127             "args %016" PRIx64 ", %016" PRIx64 ", %016" PRIx64 ", %016" PRIx64
   2128             ", %016" PRIx64 "\n",
   2129             static_cast<void*>(FUNCTION_ADDR(target)), arg1, arg2, arg3, arg4,
   2130             arg5);
   2131       }
   2132       // arg0 is a hidden argument pointing to the return location, so don't
   2133       // pass it to the target function.
   2134       ObjectTriple result = target(arg1, arg2, arg3, arg4, arg5);
   2135       if (::v8::internal::FLAG_trace_sim) {
   2136         PrintF("Returned { %p, %p, %p }\n", static_cast<void*>(result.x),
   2137                static_cast<void*>(result.y), static_cast<void*>(result.z));
   2138       }
   2139       // Return is passed back in address pointed to by hidden first argument.
   2140       ObjectTriple* sim_result = reinterpret_cast<ObjectTriple*>(arg0);
   2141       *sim_result = result;
   2142       set_register(v0, arg0);
   2143     } else {
   2144       DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
   2145              redirection->type() == ExternalReference::BUILTIN_CALL_PAIR);
   2146       SimulatorRuntimeCall target =
   2147                   reinterpret_cast<SimulatorRuntimeCall>(external);
   2148       if (::v8::internal::FLAG_trace_sim) {
   2149         PrintF(
   2150             "Call to host function at %p "
   2151             "args %08" PRIx64 " , %08" PRIx64 " , %08" PRIx64 " , %08" PRIx64
   2152             " , %08" PRIx64 " , %08" PRIx64 " \n",
   2153             static_cast<void*>(FUNCTION_ADDR(target)), arg0, arg1, arg2, arg3,
   2154             arg4, arg5);
   2155       }
   2156       // int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
   2157       // set_register(v0, static_cast<int32_t>(result));
   2158       // set_register(v1, static_cast<int32_t>(result >> 32));
   2159       ObjectPair result = target(arg0, arg1, arg2, arg3, arg4, arg5);
   2160       set_register(v0, (int64_t)(result.x));
   2161       set_register(v1, (int64_t)(result.y));
   2162     }
   2163      if (::v8::internal::FLAG_trace_sim) {
   2164        PrintF("Returned %08" PRIx64 "  : %08" PRIx64 " \n", get_register(v1),
   2165               get_register(v0));
   2166     }
   2167     set_register(ra, saved_ra);
   2168     set_pc(get_register(ra));
   2169 
   2170   } else if (func == BREAK && code <= kMaxStopCode) {
   2171     if (IsWatchpoint(code)) {
   2172       PrintWatchpoint(code);
   2173     } else {
   2174       IncreaseStopCounter(code);
   2175       HandleStop(code, instr_.instr());
   2176     }
   2177   } else {
   2178     // All remaining break_ codes, and all traps are handled here.
   2179     MipsDebugger dbg(this);
   2180     dbg.Debug();
   2181   }
   2182 }
   2183 
   2184 
   2185 // Stop helper functions.
   2186 bool Simulator::IsWatchpoint(uint64_t code) {
   2187   return (code <= kMaxWatchpointCode);
   2188 }
   2189 
   2190 
   2191 void Simulator::PrintWatchpoint(uint64_t code) {
   2192   MipsDebugger dbg(this);
   2193   ++break_count_;
   2194   PrintF("\n---- break %" PRId64 "  marker: %3d  (instr count: %8" PRId64
   2195          " ) ----------"
   2196          "----------------------------------",
   2197          code, break_count_, icount_);
   2198   dbg.PrintAllRegs();  // Print registers and continue running.
   2199 }
   2200 
   2201 
   2202 void Simulator::HandleStop(uint64_t code, Instruction* instr) {
   2203   // Stop if it is enabled, otherwise go on jumping over the stop
   2204   // and the message address.
   2205   if (IsEnabledStop(code)) {
   2206     MipsDebugger dbg(this);
   2207     dbg.Stop(instr);
   2208   } else {
   2209     set_pc(get_pc() + 2 * Instruction::kInstrSize);
   2210   }
   2211 }
   2212 
   2213 
   2214 bool Simulator::IsStopInstruction(Instruction* instr) {
   2215   int32_t func = instr->FunctionFieldRaw();
   2216   uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
   2217   return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
   2218 }
   2219 
   2220 
   2221 bool Simulator::IsEnabledStop(uint64_t code) {
   2222   DCHECK(code <= kMaxStopCode);
   2223   DCHECK(code > kMaxWatchpointCode);
   2224   return !(watched_stops_[code].count & kStopDisabledBit);
   2225 }
   2226 
   2227 
   2228 void Simulator::EnableStop(uint64_t code) {
   2229   if (!IsEnabledStop(code)) {
   2230     watched_stops_[code].count &= ~kStopDisabledBit;
   2231   }
   2232 }
   2233 
   2234 
   2235 void Simulator::DisableStop(uint64_t code) {
   2236   if (IsEnabledStop(code)) {
   2237     watched_stops_[code].count |= kStopDisabledBit;
   2238   }
   2239 }
   2240 
   2241 
   2242 void Simulator::IncreaseStopCounter(uint64_t code) {
   2243   DCHECK(code <= kMaxStopCode);
   2244   if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
   2245     PrintF("Stop counter for code %" PRId64
   2246            "  has overflowed.\n"
   2247            "Enabling this code and reseting the counter to 0.\n",
   2248            code);
   2249     watched_stops_[code].count = 0;
   2250     EnableStop(code);
   2251   } else {
   2252     watched_stops_[code].count++;
   2253   }
   2254 }
   2255 
   2256 
   2257 // Print a stop status.
   2258 void Simulator::PrintStopInfo(uint64_t code) {
   2259   if (code <= kMaxWatchpointCode) {
   2260     PrintF("That is a watchpoint, not a stop.\n");
   2261     return;
   2262   } else if (code > kMaxStopCode) {
   2263     PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
   2264     return;
   2265   }
   2266   const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled";
   2267   int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
   2268   // Don't print the state of unused breakpoints.
   2269   if (count != 0) {
   2270     if (watched_stops_[code].desc) {
   2271       PrintF("stop %" PRId64 "  - 0x%" PRIx64 " : \t%s, \tcounter = %i, \t%s\n",
   2272              code, code, state, count, watched_stops_[code].desc);
   2273     } else {
   2274       PrintF("stop %" PRId64 "  - 0x%" PRIx64 " : \t%s, \tcounter = %i\n", code,
   2275              code, state, count);
   2276     }
   2277   }
   2278 }
   2279 
   2280 
   2281 void Simulator::SignalException(Exception e) {
   2282   V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.",
   2283            static_cast<int>(e));
   2284 }
   2285 
   2286 // Min/Max template functions for Double and Single arguments.
   2287 
   2288 template <typename T>
   2289 static T FPAbs(T a);
   2290 
   2291 template <>
   2292 double FPAbs<double>(double a) {
   2293   return fabs(a);
   2294 }
   2295 
   2296 template <>
   2297 float FPAbs<float>(float a) {
   2298   return fabsf(a);
   2299 }
   2300 
   2301 template <typename T>
   2302 static bool FPUProcessNaNsAndZeros(T a, T b, MaxMinKind kind, T& result) {
   2303   if (std::isnan(a) && std::isnan(b)) {
   2304     result = a;
   2305   } else if (std::isnan(a)) {
   2306     result = b;
   2307   } else if (std::isnan(b)) {
   2308     result = a;
   2309   } else if (b == a) {
   2310     // Handle -0.0 == 0.0 case.
   2311     // std::signbit() returns int 0 or 1 so substracting MaxMinKind::kMax
   2312     // negates the result.
   2313     result = std::signbit(b) - static_cast<int>(kind) ? b : a;
   2314   } else {
   2315     return false;
   2316   }
   2317   return true;
   2318 }
   2319 
   2320 template <typename T>
   2321 static T FPUMin(T a, T b) {
   2322   T result;
   2323   if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, result)) {
   2324     return result;
   2325   } else {
   2326     return b < a ? b : a;
   2327   }
   2328 }
   2329 
   2330 template <typename T>
   2331 static T FPUMax(T a, T b) {
   2332   T result;
   2333   if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMax, result)) {
   2334     return result;
   2335   } else {
   2336     return b > a ? b : a;
   2337   }
   2338 }
   2339 
   2340 template <typename T>
   2341 static T FPUMinA(T a, T b) {
   2342   T result;
   2343   if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, result)) {
   2344     if (FPAbs(a) < FPAbs(b)) {
   2345       result = a;
   2346     } else if (FPAbs(b) < FPAbs(a)) {
   2347       result = b;
   2348     } else {
   2349       result = a < b ? a : b;
   2350     }
   2351   }
   2352   return result;
   2353 }
   2354 
   2355 template <typename T>
   2356 static T FPUMaxA(T a, T b) {
   2357   T result;
   2358   if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, result)) {
   2359     if (FPAbs(a) > FPAbs(b)) {
   2360       result = a;
   2361     } else if (FPAbs(b) > FPAbs(a)) {
   2362       result = b;
   2363     } else {
   2364       result = a > b ? a : b;
   2365     }
   2366   }
   2367   return result;
   2368 }
   2369 
   2370 enum class KeepSign : bool { no = false, yes };
   2371 
   2372 template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
   2373                                               int>::type = 0>
   2374 T FPUCanonalizeNaNArg(T result, T arg, KeepSign keepSign = KeepSign::no) {
   2375   DCHECK(std::isnan(arg));
   2376   T qNaN = std::numeric_limits<T>::quiet_NaN();
   2377   if (keepSign == KeepSign::yes) {
   2378     return std::copysign(qNaN, result);
   2379   }
   2380   return qNaN;
   2381 }
   2382 
   2383 template <typename T>
   2384 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first) {
   2385   if (std::isnan(first)) {
   2386     return FPUCanonalizeNaNArg(result, first, keepSign);
   2387   }
   2388   return result;
   2389 }
   2390 
   2391 template <typename T, typename... Args>
   2392 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first, Args... args) {
   2393   if (std::isnan(first)) {
   2394     return FPUCanonalizeNaNArg(result, first, keepSign);
   2395   }
   2396   return FPUCanonalizeNaNArgs(result, keepSign, args...);
   2397 }
   2398 
   2399 template <typename Func, typename T, typename... Args>
   2400 T FPUCanonalizeOperation(Func f, T first, Args... args) {
   2401   return FPUCanonalizeOperation(f, KeepSign::no, first, args...);
   2402 }
   2403 
   2404 template <typename Func, typename T, typename... Args>
   2405 T FPUCanonalizeOperation(Func f, KeepSign keepSign, T first, Args... args) {
   2406   T result = f(first, args...);
   2407   if (std::isnan(result)) {
   2408     result = FPUCanonalizeNaNArgs(result, keepSign, first, args...);
   2409   }
   2410   return result;
   2411 }
   2412 
   2413 // Handle execution based on instruction types.
   2414 
   2415 void Simulator::DecodeTypeRegisterSRsType() {
   2416   float fs, ft, fd;
   2417   fs = get_fpu_register_float(fs_reg());
   2418   ft = get_fpu_register_float(ft_reg());
   2419   fd = get_fpu_register_float(fd_reg());
   2420   int32_t ft_int = bit_cast<int32_t>(ft);
   2421   int32_t fd_int = bit_cast<int32_t>(fd);
   2422   uint32_t cc, fcsr_cc;
   2423   cc = instr_.FCccValue();
   2424   fcsr_cc = get_fcsr_condition_bit(cc);
   2425   switch (instr_.FunctionFieldRaw()) {
   2426     case RINT: {
   2427       DCHECK(kArchVariant == kMips64r6);
   2428       float result, temp_result;
   2429       double temp;
   2430       float upper = std::ceil(fs);
   2431       float lower = std::floor(fs);
   2432       switch (get_fcsr_rounding_mode()) {
   2433         case kRoundToNearest:
   2434           if (upper - fs < fs - lower) {
   2435             result = upper;
   2436           } else if (upper - fs > fs - lower) {
   2437             result = lower;
   2438           } else {
   2439             temp_result = upper / 2;
   2440             float reminder = modf(temp_result, &temp);
   2441             if (reminder == 0) {
   2442               result = upper;
   2443             } else {
   2444               result = lower;
   2445             }
   2446           }
   2447           break;
   2448         case kRoundToZero:
   2449           result = (fs > 0 ? lower : upper);
   2450           break;
   2451         case kRoundToPlusInf:
   2452           result = upper;
   2453           break;
   2454         case kRoundToMinusInf:
   2455           result = lower;
   2456           break;
   2457       }
   2458       set_fpu_register_float(fd_reg(), result);
   2459       if (result != fs) {
   2460         set_fcsr_bit(kFCSRInexactFlagBit, true);
   2461       }
   2462       break;
   2463     }
   2464     case ADD_S:
   2465       set_fpu_register_float(
   2466           fd_reg(),
   2467           FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; },
   2468                                  fs, ft));
   2469       break;
   2470     case SUB_S:
   2471       set_fpu_register_float(
   2472           fd_reg(),
   2473           FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; },
   2474                                  fs, ft));
   2475       break;
   2476     case MADDF_S:
   2477       DCHECK(kArchVariant == kMips64r6);
   2478       set_fpu_register_float(fd_reg(), fd + (fs * ft));
   2479       break;
   2480     case MSUBF_S:
   2481       DCHECK(kArchVariant == kMips64r6);
   2482       set_fpu_register_float(fd_reg(), fd - (fs * ft));
   2483       break;
   2484     case MUL_S:
   2485       set_fpu_register_float(
   2486           fd_reg(),
   2487           FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; },
   2488                                  fs, ft));
   2489       break;
   2490     case DIV_S:
   2491       set_fpu_register_float(
   2492           fd_reg(),
   2493           FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; },
   2494                                  fs, ft));
   2495       break;
   2496     case ABS_S:
   2497       set_fpu_register_float(
   2498           fd_reg(),
   2499           FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs));
   2500       break;
   2501     case MOV_S:
   2502       set_fpu_register_float(fd_reg(), fs);
   2503       break;
   2504     case NEG_S:
   2505       set_fpu_register_float(
   2506           fd_reg(), FPUCanonalizeOperation([](float src) { return -src; },
   2507                                            KeepSign::yes, fs));
   2508       break;
   2509     case SQRT_S:
   2510       set_fpu_register_float(
   2511           fd_reg(),
   2512           FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs));
   2513       break;
   2514     case RSQRT_S:
   2515       set_fpu_register_float(
   2516           fd_reg(), FPUCanonalizeOperation(
   2517                         [](float src) { return 1.0 / std::sqrt(src); }, fs));
   2518       break;
   2519     case RECIP_S:
   2520       set_fpu_register_float(
   2521           fd_reg(),
   2522           FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs));
   2523       break;
   2524     case C_F_D:
   2525       set_fcsr_bit(fcsr_cc, false);
   2526       break;
   2527     case C_UN_D:
   2528       set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
   2529       break;
   2530     case C_EQ_D:
   2531       set_fcsr_bit(fcsr_cc, (fs == ft));
   2532       break;
   2533     case C_UEQ_D:
   2534       set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
   2535       break;
   2536     case C_OLT_D:
   2537       set_fcsr_bit(fcsr_cc, (fs < ft));
   2538       break;
   2539     case C_ULT_D:
   2540       set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
   2541       break;
   2542     case C_OLE_D:
   2543       set_fcsr_bit(fcsr_cc, (fs <= ft));
   2544       break;
   2545     case C_ULE_D:
   2546       set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
   2547       break;
   2548     case CVT_D_S:
   2549       set_fpu_register_double(fd_reg(), static_cast<double>(fs));
   2550       break;
   2551     case CLASS_S: {  // Mips64r6 instruction
   2552       // Convert float input to uint32_t for easier bit manipulation
   2553       uint32_t classed = bit_cast<uint32_t>(fs);
   2554 
   2555       // Extracting sign, exponent and mantissa from the input float
   2556       uint32_t sign = (classed >> 31) & 1;
   2557       uint32_t exponent = (classed >> 23) & 0x000000ff;
   2558       uint32_t mantissa = classed & 0x007fffff;
   2559       uint32_t result;
   2560       float fResult;
   2561 
   2562       // Setting flags if input float is negative infinity,
   2563       // positive infinity, negative zero or positive zero
   2564       bool negInf = (classed == 0xFF800000);
   2565       bool posInf = (classed == 0x7F800000);
   2566       bool negZero = (classed == 0x80000000);
   2567       bool posZero = (classed == 0x00000000);
   2568 
   2569       bool signalingNan;
   2570       bool quietNan;
   2571       bool negSubnorm;
   2572       bool posSubnorm;
   2573       bool negNorm;
   2574       bool posNorm;
   2575 
   2576       // Setting flags if float is NaN
   2577       signalingNan = false;
   2578       quietNan = false;
   2579       if (!negInf && !posInf && (exponent == 0xff)) {
   2580         quietNan = ((mantissa & 0x00200000) == 0) &&
   2581                    ((mantissa & (0x00200000 - 1)) == 0);
   2582         signalingNan = !quietNan;
   2583       }
   2584 
   2585       // Setting flags if float is subnormal number
   2586       posSubnorm = false;
   2587       negSubnorm = false;
   2588       if ((exponent == 0) && (mantissa != 0)) {
   2589         DCHECK(sign == 0 || sign == 1);
   2590         posSubnorm = (sign == 0);
   2591         negSubnorm = (sign == 1);
   2592       }
   2593 
   2594       // Setting flags if float is normal number
   2595       posNorm = false;
   2596       negNorm = false;
   2597       if (!posSubnorm && !negSubnorm && !posInf && !negInf && !signalingNan &&
   2598           !quietNan && !negZero && !posZero) {
   2599         DCHECK(sign == 0 || sign == 1);
   2600         posNorm = (sign == 0);
   2601         negNorm = (sign == 1);
   2602       }
   2603 
   2604       // Calculating result according to description of CLASS.S instruction
   2605       result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
   2606                (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
   2607                (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
   2608 
   2609       DCHECK(result != 0);
   2610 
   2611       fResult = bit_cast<float>(result);
   2612       set_fpu_register_float(fd_reg(), fResult);
   2613 
   2614       break;
   2615     }
   2616     case CVT_L_S: {
   2617       float rounded;
   2618       int64_t result;
   2619       round64_according_to_fcsr(fs, rounded, result, fs);
   2620       set_fpu_register(fd_reg(), result);
   2621       if (set_fcsr_round64_error(fs, rounded)) {
   2622         set_fpu_register_invalid_result64(fs, rounded);
   2623       }
   2624       break;
   2625     }
   2626     case CVT_W_S: {
   2627       float rounded;
   2628       int32_t result;
   2629       round_according_to_fcsr(fs, rounded, result, fs);
   2630       set_fpu_register_word(fd_reg(), result);
   2631       if (set_fcsr_round_error(fs, rounded)) {
   2632         set_fpu_register_word_invalid_result(fs, rounded);
   2633       }
   2634       break;
   2635     }
   2636     case TRUNC_W_S: {  // Truncate single to word (round towards 0).
   2637       float rounded = trunc(fs);
   2638       int32_t result = static_cast<int32_t>(rounded);
   2639       set_fpu_register_word(fd_reg(), result);
   2640       if (set_fcsr_round_error(fs, rounded)) {
   2641         set_fpu_register_word_invalid_result(fs, rounded);
   2642       }
   2643     } break;
   2644     case TRUNC_L_S: {  // Mips64r2 instruction.
   2645       float rounded = trunc(fs);
   2646       int64_t result = static_cast<int64_t>(rounded);
   2647       set_fpu_register(fd_reg(), result);
   2648       if (set_fcsr_round64_error(fs, rounded)) {
   2649         set_fpu_register_invalid_result64(fs, rounded);
   2650       }
   2651       break;
   2652     }
   2653     case ROUND_W_S: {
   2654       float rounded = std::floor(fs + 0.5);
   2655       int32_t result = static_cast<int32_t>(rounded);
   2656       if ((result & 1) != 0 && result - fs == 0.5) {
   2657         // If the number is halfway between two integers,
   2658         // round to the even one.
   2659         result--;
   2660       }
   2661       set_fpu_register_word(fd_reg(), result);
   2662       if (set_fcsr_round_error(fs, rounded)) {
   2663         set_fpu_register_word_invalid_result(fs, rounded);
   2664       }
   2665       break;
   2666     }
   2667     case ROUND_L_S: {  // Mips64r2 instruction.
   2668       float rounded = std::floor(fs + 0.5);
   2669       int64_t result = static_cast<int64_t>(rounded);
   2670       if ((result & 1) != 0 && result - fs == 0.5) {
   2671         // If the number is halfway between two integers,
   2672         // round to the even one.
   2673         result--;
   2674       }
   2675       int64_t i64 = static_cast<int64_t>(result);
   2676       set_fpu_register(fd_reg(), i64);
   2677       if (set_fcsr_round64_error(fs, rounded)) {
   2678         set_fpu_register_invalid_result64(fs, rounded);
   2679       }
   2680       break;
   2681     }
   2682     case FLOOR_L_S: {  // Mips64r2 instruction.
   2683       float rounded = floor(fs);
   2684       int64_t result = static_cast<int64_t>(rounded);
   2685       set_fpu_register(fd_reg(), result);
   2686       if (set_fcsr_round64_error(fs, rounded)) {
   2687         set_fpu_register_invalid_result64(fs, rounded);
   2688       }
   2689       break;
   2690     }
   2691     case FLOOR_W_S:  // Round double to word towards negative infinity.
   2692     {
   2693       float rounded = std::floor(fs);
   2694       int32_t result = static_cast<int32_t>(rounded);
   2695       set_fpu_register_word(fd_reg(), result);
   2696       if (set_fcsr_round_error(fs, rounded)) {
   2697         set_fpu_register_word_invalid_result(fs, rounded);
   2698       }
   2699     } break;
   2700     case CEIL_W_S:  // Round double to word towards positive infinity.
   2701     {
   2702       float rounded = std::ceil(fs);
   2703       int32_t result = static_cast<int32_t>(rounded);
   2704       set_fpu_register_word(fd_reg(), result);
   2705       if (set_fcsr_round_error(fs, rounded)) {
   2706         set_fpu_register_invalid_result(fs, rounded);
   2707       }
   2708     } break;
   2709     case CEIL_L_S: {  // Mips64r2 instruction.
   2710       float rounded = ceil(fs);
   2711       int64_t result = static_cast<int64_t>(rounded);
   2712       set_fpu_register(fd_reg(), result);
   2713       if (set_fcsr_round64_error(fs, rounded)) {
   2714         set_fpu_register_invalid_result64(fs, rounded);
   2715       }
   2716       break;
   2717     }
   2718     case MINA:
   2719       DCHECK(kArchVariant == kMips64r6);
   2720       set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
   2721       break;
   2722     case MAXA:
   2723       DCHECK(kArchVariant == kMips64r6);
   2724       set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
   2725       break;
   2726     case MIN:
   2727       DCHECK(kArchVariant == kMips64r6);
   2728       set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
   2729       break;
   2730     case MAX:
   2731       DCHECK(kArchVariant == kMips64r6);
   2732       set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
   2733       break;
   2734     case SEL:
   2735       DCHECK(kArchVariant == kMips64r6);
   2736       set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
   2737       break;
   2738     case SELEQZ_C:
   2739       DCHECK(kArchVariant == kMips64r6);
   2740       set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0
   2741                                            ? get_fpu_register_float(fs_reg())
   2742                                            : 0.0);
   2743       break;
   2744     case SELNEZ_C:
   2745       DCHECK(kArchVariant == kMips64r6);
   2746       set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0
   2747                                            ? get_fpu_register_float(fs_reg())
   2748                                            : 0.0);
   2749       break;
   2750     case MOVZ_C: {
   2751       DCHECK(kArchVariant == kMips64r2);
   2752       if (rt() == 0) {
   2753         set_fpu_register_float(fd_reg(), fs);
   2754       }
   2755       break;
   2756     }
   2757     case MOVN_C: {
   2758       DCHECK(kArchVariant == kMips64r2);
   2759       if (rt() != 0) {
   2760         set_fpu_register_float(fd_reg(), fs);
   2761       }
   2762       break;
   2763     }
   2764     case MOVF: {
   2765       // Same function field for MOVT.D and MOVF.D
   2766       uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
   2767       ft_cc = get_fcsr_condition_bit(ft_cc);
   2768 
   2769       if (instr_.Bit(16)) {  // Read Tf bit.
   2770         // MOVT.D
   2771         if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
   2772       } else {
   2773         // MOVF.D
   2774         if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
   2775       }
   2776       break;
   2777     }
   2778     default:
   2779       // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
   2780       // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
   2781       UNREACHABLE();
   2782   }
   2783 }
   2784 
   2785 
   2786 void Simulator::DecodeTypeRegisterDRsType() {
   2787   double ft, fs, fd;
   2788   uint32_t cc, fcsr_cc;
   2789   fs = get_fpu_register_double(fs_reg());
   2790   ft = (instr_.FunctionFieldRaw() != MOVF) ? get_fpu_register_double(ft_reg())
   2791                                            : 0.0;
   2792   fd = get_fpu_register_double(fd_reg());
   2793   cc = instr_.FCccValue();
   2794   fcsr_cc = get_fcsr_condition_bit(cc);
   2795   int64_t ft_int = bit_cast<int64_t>(ft);
   2796   int64_t fd_int = bit_cast<int64_t>(fd);
   2797   switch (instr_.FunctionFieldRaw()) {
   2798     case RINT: {
   2799       DCHECK(kArchVariant == kMips64r6);
   2800       double result, temp, temp_result;
   2801       double upper = std::ceil(fs);
   2802       double lower = std::floor(fs);
   2803       switch (get_fcsr_rounding_mode()) {
   2804         case kRoundToNearest:
   2805           if (upper - fs < fs - lower) {
   2806             result = upper;
   2807           } else if (upper - fs > fs - lower) {
   2808             result = lower;
   2809           } else {
   2810             temp_result = upper / 2;
   2811             double reminder = modf(temp_result, &temp);
   2812             if (reminder == 0) {
   2813               result = upper;
   2814             } else {
   2815               result = lower;
   2816             }
   2817           }
   2818           break;
   2819         case kRoundToZero:
   2820           result = (fs > 0 ? lower : upper);
   2821           break;
   2822         case kRoundToPlusInf:
   2823           result = upper;
   2824           break;
   2825         case kRoundToMinusInf:
   2826           result = lower;
   2827           break;
   2828       }
   2829       set_fpu_register_double(fd_reg(), result);
   2830       if (result != fs) {
   2831         set_fcsr_bit(kFCSRInexactFlagBit, true);
   2832       }
   2833       break;
   2834     }
   2835     case SEL:
   2836       DCHECK(kArchVariant == kMips64r6);
   2837       set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
   2838       break;
   2839     case SELEQZ_C:
   2840       DCHECK(kArchVariant == kMips64r6);
   2841       set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0);
   2842       break;
   2843     case SELNEZ_C:
   2844       DCHECK(kArchVariant == kMips64r6);
   2845       set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0);
   2846       break;
   2847     case MOVZ_C: {
   2848       DCHECK(kArchVariant == kMips64r2);
   2849       if (rt() == 0) {
   2850         set_fpu_register_double(fd_reg(), fs);
   2851       }
   2852       break;
   2853     }
   2854     case MOVN_C: {
   2855       DCHECK(kArchVariant == kMips64r2);
   2856       if (rt() != 0) {
   2857         set_fpu_register_double(fd_reg(), fs);
   2858       }
   2859       break;
   2860     }
   2861     case MOVF: {
   2862       // Same function field for MOVT.D and MOVF.D
   2863       uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
   2864       ft_cc = get_fcsr_condition_bit(ft_cc);
   2865       if (instr_.Bit(16)) {  // Read Tf bit.
   2866         // MOVT.D
   2867         if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
   2868       } else {
   2869         // MOVF.D
   2870         if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
   2871       }
   2872       break;
   2873     }
   2874     case MINA:
   2875       DCHECK(kArchVariant == kMips64r6);
   2876       set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
   2877       break;
   2878     case MAXA:
   2879       DCHECK(kArchVariant == kMips64r6);
   2880       set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
   2881       break;
   2882     case MIN:
   2883       DCHECK(kArchVariant == kMips64r6);
   2884       set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
   2885       break;
   2886     case MAX:
   2887       DCHECK(kArchVariant == kMips64r6);
   2888       set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
   2889       break;
   2890     case ADD_D:
   2891       set_fpu_register_double(
   2892           fd_reg(),
   2893           FPUCanonalizeOperation(
   2894               [](double lhs, double rhs) { return lhs + rhs; }, fs, ft));
   2895       break;
   2896     case SUB_D:
   2897       set_fpu_register_double(
   2898           fd_reg(),
   2899           FPUCanonalizeOperation(
   2900               [](double lhs, double rhs) { return lhs - rhs; }, fs, ft));
   2901       break;
   2902     case MADDF_D:
   2903       DCHECK(kArchVariant == kMips64r6);
   2904       set_fpu_register_double(fd_reg(), fd + (fs * ft));
   2905       break;
   2906     case MSUBF_D:
   2907       DCHECK(kArchVariant == kMips64r6);
   2908       set_fpu_register_double(fd_reg(), fd - (fs * ft));
   2909       break;
   2910     case MUL_D:
   2911       set_fpu_register_double(
   2912           fd_reg(),
   2913           FPUCanonalizeOperation(
   2914               [](double lhs, double rhs) { return lhs * rhs; }, fs, ft));
   2915       break;
   2916     case DIV_D:
   2917       set_fpu_register_double(
   2918           fd_reg(),
   2919           FPUCanonalizeOperation(
   2920               [](double lhs, double rhs) { return lhs / rhs; }, fs, ft));
   2921       break;
   2922     case ABS_D:
   2923       set_fpu_register_double(
   2924           fd_reg(),
   2925           FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs));
   2926       break;
   2927     case MOV_D:
   2928       set_fpu_register_double(fd_reg(), fs);
   2929       break;
   2930     case NEG_D:
   2931       set_fpu_register_double(
   2932           fd_reg(), FPUCanonalizeOperation([](double src) { return -src; },
   2933                                            KeepSign::yes, fs));
   2934       break;
   2935     case SQRT_D:
   2936       set_fpu_register_double(
   2937           fd_reg(),
   2938           FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs));
   2939       break;
   2940     case RSQRT_D:
   2941       set_fpu_register_double(
   2942           fd_reg(), FPUCanonalizeOperation(
   2943                         [](double fs) { return 1.0 / std::sqrt(fs); }, fs));
   2944       break;
   2945     case RECIP_D:
   2946       set_fpu_register_double(
   2947           fd_reg(),
   2948           FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs));
   2949       break;
   2950     case C_UN_D:
   2951       set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
   2952       break;
   2953     case C_EQ_D:
   2954       set_fcsr_bit(fcsr_cc, (fs == ft));
   2955       break;
   2956     case C_UEQ_D:
   2957       set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
   2958       break;
   2959     case C_OLT_D:
   2960       set_fcsr_bit(fcsr_cc, (fs < ft));
   2961       break;
   2962     case C_ULT_D:
   2963       set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
   2964       break;
   2965     case C_OLE_D:
   2966       set_fcsr_bit(fcsr_cc, (fs <= ft));
   2967       break;
   2968     case C_ULE_D:
   2969       set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
   2970       break;
   2971     case CVT_W_D: {  // Convert double to word.
   2972       double rounded;
   2973       int32_t result;
   2974       round_according_to_fcsr(fs, rounded, result, fs);
   2975       set_fpu_register_word(fd_reg(), result);
   2976       if (set_fcsr_round_error(fs, rounded)) {
   2977         set_fpu_register_word_invalid_result(fs, rounded);
   2978       }
   2979       break;
   2980     }
   2981     case ROUND_W_D:  // Round double to word (round half to even).
   2982     {
   2983       double rounded = std::floor(fs + 0.5);
   2984       int32_t result = static_cast<int32_t>(rounded);
   2985       if ((result & 1) != 0 && result - fs == 0.5) {
   2986         // If the number is halfway between two integers,
   2987         // round to the even one.
   2988         result--;
   2989       }
   2990       set_fpu_register_word(fd_reg(), result);
   2991       if (set_fcsr_round_error(fs, rounded)) {
   2992         set_fpu_register_invalid_result(fs, rounded);
   2993       }
   2994     } break;
   2995     case TRUNC_W_D:  // Truncate double to word (round towards 0).
   2996     {
   2997       double rounded = trunc(fs);
   2998       int32_t result = static_cast<int32_t>(rounded);
   2999       set_fpu_register_word(fd_reg(), result);
   3000       if (set_fcsr_round_error(fs, rounded)) {
   3001         set_fpu_register_invalid_result(fs, rounded);
   3002       }
   3003     } break;
   3004     case FLOOR_W_D:  // Round double to word towards negative infinity.
   3005     {
   3006       double rounded = std::floor(fs);
   3007       int32_t result = static_cast<int32_t>(rounded);
   3008       set_fpu_register_word(fd_reg(), result);
   3009       if (set_fcsr_round_error(fs, rounded)) {
   3010         set_fpu_register_invalid_result(fs, rounded);
   3011       }
   3012     } break;
   3013     case CEIL_W_D:  // Round double to word towards positive infinity.
   3014     {
   3015       double rounded = std::ceil(fs);
   3016       int32_t result = static_cast<int32_t>(rounded);
   3017       set_fpu_register_word(fd_reg(), result);
   3018       if (set_fcsr_round_error(fs, rounded)) {
   3019         set_fpu_register_invalid_result(fs, rounded);
   3020       }
   3021     } break;
   3022     case CVT_S_D:  // Convert double to float (single).
   3023       set_fpu_register_float(fd_reg(), static_cast<float>(fs));
   3024       break;
   3025     case CVT_L_D: {  // Mips64r2: Truncate double to 64-bit long-word.
   3026       double rounded;
   3027       int64_t result;
   3028       round64_according_to_fcsr(fs, rounded, result, fs);
   3029       set_fpu_register(fd_reg(), result);
   3030       if (set_fcsr_round64_error(fs, rounded)) {
   3031         set_fpu_register_invalid_result64(fs, rounded);
   3032       }
   3033       break;
   3034     }
   3035     case ROUND_L_D: {  // Mips64r2 instruction.
   3036       double rounded = std::floor(fs + 0.5);
   3037       int64_t result = static_cast<int64_t>(rounded);
   3038       if ((result & 1) != 0 && result - fs == 0.5) {
   3039         // If the number is halfway between two integers,
   3040         // round to the even one.
   3041         result--;
   3042       }
   3043       int64_t i64 = static_cast<int64_t>(result);
   3044       set_fpu_register(fd_reg(), i64);
   3045       if (set_fcsr_round64_error(fs, rounded)) {
   3046         set_fpu_register_invalid_result64(fs, rounded);
   3047       }
   3048       break;
   3049     }
   3050     case TRUNC_L_D: {  // Mips64r2 instruction.
   3051       double rounded = trunc(fs);
   3052       int64_t result = static_cast<int64_t>(rounded);
   3053       set_fpu_register(fd_reg(), result);
   3054       if (set_fcsr_round64_error(fs, rounded)) {
   3055         set_fpu_register_invalid_result64(fs, rounded);
   3056       }
   3057       break;
   3058     }
   3059     case FLOOR_L_D: {  // Mips64r2 instruction.
   3060       double rounded = floor(fs);
   3061       int64_t result = static_cast<int64_t>(rounded);
   3062       set_fpu_register(fd_reg(), result);
   3063       if (set_fcsr_round64_error(fs, rounded)) {
   3064         set_fpu_register_invalid_result64(fs, rounded);
   3065       }
   3066       break;
   3067     }
   3068     case CEIL_L_D: {  // Mips64r2 instruction.
   3069       double rounded = ceil(fs);
   3070       int64_t result = static_cast<int64_t>(rounded);
   3071       set_fpu_register(fd_reg(), result);
   3072       if (set_fcsr_round64_error(fs, rounded)) {
   3073         set_fpu_register_invalid_result64(fs, rounded);
   3074       }
   3075       break;
   3076     }
   3077     case CLASS_D: {  // Mips64r6 instruction
   3078       // Convert double input to uint64_t for easier bit manipulation
   3079       uint64_t classed = bit_cast<uint64_t>(fs);
   3080 
   3081       // Extracting sign, exponent and mantissa from the input double
   3082       uint32_t sign = (classed >> 63) & 1;
   3083       uint32_t exponent = (classed >> 52) & 0x00000000000007ff;
   3084       uint64_t mantissa = classed & 0x000fffffffffffff;
   3085       uint64_t result;
   3086       double dResult;
   3087 
   3088       // Setting flags if input double is negative infinity,
   3089       // positive infinity, negative zero or positive zero
   3090       bool negInf = (classed == 0xFFF0000000000000);
   3091       bool posInf = (classed == 0x7FF0000000000000);
   3092       bool negZero = (classed == 0x8000000000000000);
   3093       bool posZero = (classed == 0x0000000000000000);
   3094 
   3095       bool signalingNan;
   3096       bool quietNan;
   3097       bool negSubnorm;
   3098       bool posSubnorm;
   3099       bool negNorm;
   3100       bool posNorm;
   3101 
   3102       // Setting flags if double is NaN
   3103       signalingNan = false;
   3104       quietNan = false;
   3105       if (!negInf && !posInf && exponent == 0x7ff) {
   3106         quietNan = ((mantissa & 0x0008000000000000) != 0) &&
   3107                    ((mantissa & (0x0008000000000000 - 1)) == 0);
   3108         signalingNan = !quietNan;
   3109       }
   3110 
   3111       // Setting flags if double is subnormal number
   3112       posSubnorm = false;
   3113       negSubnorm = false;
   3114       if ((exponent == 0) && (mantissa != 0)) {
   3115         DCHECK(sign == 0 || sign == 1);
   3116         posSubnorm = (sign == 0);
   3117         negSubnorm = (sign == 1);
   3118       }
   3119 
   3120       // Setting flags if double is normal number
   3121       posNorm = false;
   3122       negNorm = false;
   3123       if (!posSubnorm && !negSubnorm && !posInf && !negInf && !signalingNan &&
   3124           !quietNan && !negZero && !posZero) {
   3125         DCHECK(sign == 0 || sign == 1);
   3126         posNorm = (sign == 0);
   3127         negNorm = (sign == 1);
   3128       }
   3129 
   3130       // Calculating result according to description of CLASS.D instruction
   3131       result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
   3132                (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
   3133                (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
   3134 
   3135       DCHECK(result != 0);
   3136 
   3137       dResult = bit_cast<double>(result);
   3138       set_fpu_register_double(fd_reg(), dResult);
   3139 
   3140       break;
   3141     }
   3142     case C_F_D: {
   3143       set_fcsr_bit(fcsr_cc, false);
   3144       break;
   3145     }
   3146     default:
   3147       UNREACHABLE();
   3148   }
   3149 }
   3150 
   3151 
   3152 void Simulator::DecodeTypeRegisterWRsType() {
   3153   float fs = get_fpu_register_float(fs_reg());
   3154   float ft = get_fpu_register_float(ft_reg());
   3155   int64_t alu_out = 0x12345678;
   3156   switch (instr_.FunctionFieldRaw()) {
   3157     case CVT_S_W:  // Convert word to float (single).
   3158       alu_out = get_fpu_register_signed_word(fs_reg());
   3159       set_fpu_register_float(fd_reg(), static_cast<float>(alu_out));
   3160       break;
   3161     case CVT_D_W:  // Convert word to double.
   3162       alu_out = get_fpu_register_signed_word(fs_reg());
   3163       set_fpu_register_double(fd_reg(), static_cast<double>(alu_out));
   3164       break;
   3165     case CMP_AF:
   3166       set_fpu_register_word(fd_reg(), 0);
   3167       break;
   3168     case CMP_UN:
   3169       if (std::isnan(fs) || std::isnan(ft)) {
   3170         set_fpu_register_word(fd_reg(), -1);
   3171       } else {
   3172         set_fpu_register_word(fd_reg(), 0);
   3173       }
   3174       break;
   3175     case CMP_EQ:
   3176       if (fs == ft) {
   3177         set_fpu_register_word(fd_reg(), -1);
   3178       } else {
   3179         set_fpu_register_word(fd_reg(), 0);
   3180       }
   3181       break;
   3182     case CMP_UEQ:
   3183       if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
   3184         set_fpu_register_word(fd_reg(), -1);
   3185       } else {
   3186         set_fpu_register_word(fd_reg(), 0);
   3187       }
   3188       break;
   3189     case CMP_LT:
   3190       if (fs < ft) {
   3191         set_fpu_register_word(fd_reg(), -1);
   3192       } else {
   3193         set_fpu_register_word(fd_reg(), 0);
   3194       }
   3195       break;
   3196     case CMP_ULT:
   3197       if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
   3198         set_fpu_register_word(fd_reg(), -1);
   3199       } else {
   3200         set_fpu_register_word(fd_reg(), 0);
   3201       }
   3202       break;
   3203     case CMP_LE:
   3204       if (fs <= ft) {
   3205         set_fpu_register_word(fd_reg(), -1);
   3206       } else {
   3207         set_fpu_register_word(fd_reg(), 0);
   3208       }
   3209       break;
   3210     case CMP_ULE:
   3211       if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
   3212         set_fpu_register_word(fd_reg(), -1);
   3213       } else {
   3214         set_fpu_register_word(fd_reg(), 0);
   3215       }
   3216       break;
   3217     case CMP_OR:
   3218       if (!std::isnan(fs) && !std::isnan(ft)) {
   3219         set_fpu_register_word(fd_reg(), -1);
   3220       } else {
   3221         set_fpu_register_word(fd_reg(), 0);
   3222       }
   3223       break;
   3224     case CMP_UNE:
   3225       if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
   3226         set_fpu_register_word(fd_reg(), -1);
   3227       } else {
   3228         set_fpu_register_word(fd_reg(), 0);
   3229       }
   3230       break;
   3231     case CMP_NE:
   3232       if (fs != ft) {
   3233         set_fpu_register_word(fd_reg(), -1);
   3234       } else {
   3235         set_fpu_register_word(fd_reg(), 0);
   3236       }
   3237       break;
   3238     default:
   3239       UNREACHABLE();
   3240   }
   3241 }
   3242 
   3243 
   3244 void Simulator::DecodeTypeRegisterLRsType() {
   3245   double fs = get_fpu_register_double(fs_reg());
   3246   double ft = get_fpu_register_double(ft_reg());
   3247   int64_t i64;
   3248   switch (instr_.FunctionFieldRaw()) {
   3249     case CVT_D_L:  // Mips32r2 instruction.
   3250       i64 = get_fpu_register(fs_reg());
   3251       set_fpu_register_double(fd_reg(), static_cast<double>(i64));
   3252       break;
   3253     case CVT_S_L:
   3254       i64 = get_fpu_register(fs_reg());
   3255       set_fpu_register_float(fd_reg(), static_cast<float>(i64));
   3256       break;
   3257     case CMP_AF:
   3258       set_fpu_register(fd_reg(), 0);
   3259       break;
   3260     case CMP_UN:
   3261       if (std::isnan(fs) || std::isnan(ft)) {
   3262         set_fpu_register(fd_reg(), -1);
   3263       } else {
   3264         set_fpu_register(fd_reg(), 0);
   3265       }
   3266       break;
   3267     case CMP_EQ:
   3268       if (fs == ft) {
   3269         set_fpu_register(fd_reg(), -1);
   3270       } else {
   3271         set_fpu_register(fd_reg(), 0);
   3272       }
   3273       break;
   3274     case CMP_UEQ:
   3275       if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
   3276         set_fpu_register(fd_reg(), -1);
   3277       } else {
   3278         set_fpu_register(fd_reg(), 0);
   3279       }
   3280       break;
   3281     case CMP_LT:
   3282       if (fs < ft) {
   3283         set_fpu_register(fd_reg(), -1);
   3284       } else {
   3285         set_fpu_register(fd_reg(), 0);
   3286       }
   3287       break;
   3288     case CMP_ULT:
   3289       if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
   3290         set_fpu_register(fd_reg(), -1);
   3291       } else {
   3292         set_fpu_register(fd_reg(), 0);
   3293       }
   3294       break;
   3295     case CMP_LE:
   3296       if (fs <= ft) {
   3297         set_fpu_register(fd_reg(), -1);
   3298       } else {
   3299         set_fpu_register(fd_reg(), 0);
   3300       }
   3301       break;
   3302     case CMP_ULE:
   3303       if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
   3304         set_fpu_register(fd_reg(), -1);
   3305       } else {
   3306         set_fpu_register(fd_reg(), 0);
   3307       }
   3308       break;
   3309     case CMP_OR:
   3310       if (!std::isnan(fs) && !std::isnan(ft)) {
   3311         set_fpu_register(fd_reg(), -1);
   3312       } else {
   3313         set_fpu_register(fd_reg(), 0);
   3314       }
   3315       break;
   3316     case CMP_UNE:
   3317       if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
   3318         set_fpu_register(fd_reg(), -1);
   3319       } else {
   3320         set_fpu_register(fd_reg(), 0);
   3321       }
   3322       break;
   3323     case CMP_NE:
   3324       if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) {
   3325         set_fpu_register(fd_reg(), -1);
   3326       } else {
   3327         set_fpu_register(fd_reg(), 0);
   3328       }
   3329       break;
   3330     default:
   3331       UNREACHABLE();
   3332   }
   3333 }
   3334 
   3335 
   3336 void Simulator::DecodeTypeRegisterCOP1() {
   3337   switch (instr_.RsFieldRaw()) {
   3338     case BC1:  // Branch on coprocessor condition.
   3339     case BC1EQZ:
   3340     case BC1NEZ:
   3341       UNREACHABLE();
   3342       break;
   3343     case CFC1:
   3344       // At the moment only FCSR is supported.
   3345       DCHECK(fs_reg() == kFCSRRegister);
   3346       set_register(rt_reg(), FCSR_);
   3347       break;
   3348     case MFC1:
   3349       set_register(rt_reg(),
   3350                    static_cast<int64_t>(get_fpu_register_word(fs_reg())));
   3351       break;
   3352     case DMFC1:
   3353       set_register(rt_reg(), get_fpu_register(fs_reg()));
   3354       break;
   3355     case MFHC1:
   3356       set_register(rt_reg(), get_fpu_register_hi_word(fs_reg()));
   3357       break;
   3358     case CTC1: {
   3359       // At the moment only FCSR is supported.
   3360       DCHECK(fs_reg() == kFCSRRegister);
   3361       uint32_t reg = static_cast<uint32_t>(rt());
   3362       if (kArchVariant == kMips64r6) {
   3363         FCSR_ = reg | kFCSRNaN2008FlagMask;
   3364       } else {
   3365         DCHECK(kArchVariant == kMips64r2);
   3366         FCSR_ = reg & ~kFCSRNaN2008FlagMask;
   3367       }
   3368       break;
   3369     }
   3370     case MTC1:
   3371       // Hardware writes upper 32-bits to zero on mtc1.
   3372       set_fpu_register_hi_word(fs_reg(), 0);
   3373       set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt()));
   3374       break;
   3375     case DMTC1:
   3376       set_fpu_register(fs_reg(), rt());
   3377       break;
   3378     case MTHC1:
   3379       set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt()));
   3380       break;
   3381     case S:
   3382       DecodeTypeRegisterSRsType();
   3383       break;
   3384     case D:
   3385       DecodeTypeRegisterDRsType();
   3386       break;
   3387     case W:
   3388       DecodeTypeRegisterWRsType();
   3389       break;
   3390     case L:
   3391       DecodeTypeRegisterLRsType();
   3392       break;
   3393     default:
   3394       UNREACHABLE();
   3395   }
   3396 }
   3397 
   3398 
   3399 void Simulator::DecodeTypeRegisterCOP1X() {
   3400   switch (instr_.FunctionFieldRaw()) {
   3401     case MADD_S: {
   3402       DCHECK(kArchVariant == kMips64r2);
   3403       float fr, ft, fs;
   3404       fr = get_fpu_register_float(fr_reg());
   3405       fs = get_fpu_register_float(fs_reg());
   3406       ft = get_fpu_register_float(ft_reg());
   3407       set_fpu_register_float(fd_reg(), fs * ft + fr);
   3408       break;
   3409     }
   3410     case MSUB_S: {
   3411       DCHECK(kArchVariant == kMips64r2);
   3412       float fr, ft, fs;
   3413       fr = get_fpu_register_float(fr_reg());
   3414       fs = get_fpu_register_float(fs_reg());
   3415       ft = get_fpu_register_float(ft_reg());
   3416       set_fpu_register_float(fd_reg(), fs * ft - fr);
   3417       break;
   3418     }
   3419     case MADD_D: {
   3420       DCHECK(kArchVariant == kMips64r2);
   3421       double fr, ft, fs;
   3422       fr = get_fpu_register_double(fr_reg());
   3423       fs = get_fpu_register_double(fs_reg());
   3424       ft = get_fpu_register_double(ft_reg());
   3425       set_fpu_register_double(fd_reg(), fs * ft + fr);
   3426       break;
   3427     }
   3428     case MSUB_D: {
   3429       DCHECK(kArchVariant == kMips64r2);
   3430       double fr, ft, fs;
   3431       fr = get_fpu_register_double(fr_reg());
   3432       fs = get_fpu_register_double(fs_reg());
   3433       ft = get_fpu_register_double(ft_reg());
   3434       set_fpu_register_double(fd_reg(), fs * ft - fr);
   3435       break;
   3436     }
   3437     default:
   3438       UNREACHABLE();
   3439   }
   3440 }
   3441 
   3442 
   3443 void Simulator::DecodeTypeRegisterSPECIAL() {
   3444   int64_t i64hilo;
   3445   uint64_t u64hilo;
   3446   int64_t alu_out;
   3447   bool do_interrupt = false;
   3448 
   3449   switch (instr_.FunctionFieldRaw()) {
   3450     case SELEQZ_S:
   3451       DCHECK(kArchVariant == kMips64r6);
   3452       set_register(rd_reg(), rt() == 0 ? rs() : 0);
   3453       break;
   3454     case SELNEZ_S:
   3455       DCHECK(kArchVariant == kMips64r6);
   3456       set_register(rd_reg(), rt() != 0 ? rs() : 0);
   3457       break;
   3458     case JR: {
   3459       int64_t next_pc = rs();
   3460       int64_t current_pc = get_pc();
   3461       Instruction* branch_delay_instr =
   3462           reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
   3463       BranchDelayInstructionDecode(branch_delay_instr);
   3464       set_pc(next_pc);
   3465       pc_modified_ = true;
   3466       break;
   3467     }
   3468     case JALR: {
   3469       int64_t next_pc = rs();
   3470       int64_t current_pc = get_pc();
   3471       int32_t return_addr_reg = rd_reg();
   3472       Instruction* branch_delay_instr =
   3473           reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
   3474       BranchDelayInstructionDecode(branch_delay_instr);
   3475       set_register(return_addr_reg, current_pc + 2 * Instruction::kInstrSize);
   3476       set_pc(next_pc);
   3477       pc_modified_ = true;
   3478       break;
   3479     }
   3480     case SLL:
   3481       SetResult(rd_reg(), static_cast<int32_t>(rt()) << sa());
   3482       break;
   3483     case DSLL:
   3484       SetResult(rd_reg(), rt() << sa());
   3485       break;
   3486     case DSLL32:
   3487       SetResult(rd_reg(), rt() << sa() << 32);
   3488       break;
   3489     case SRL:
   3490       if (rs_reg() == 0) {
   3491         // Regular logical right shift of a word by a fixed number of
   3492         // bits instruction. RS field is always equal to 0.
   3493         // Sign-extend the 32-bit result.
   3494         alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u()) >> sa());
   3495       } else if (rs_reg() == 1) {
   3496         // Logical right-rotate of a word by a fixed number of bits. This
   3497         // is special case of SRL instruction, added in MIPS32 Release 2.
   3498         // RS field is equal to 00001.
   3499         alu_out = static_cast<int32_t>(
   3500             base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()),
   3501                                       static_cast<const uint32_t>(sa())));
   3502       } else {
   3503         UNREACHABLE();
   3504       }
   3505       SetResult(rd_reg(), alu_out);
   3506       break;
   3507     case DSRL:
   3508       if (rs_reg() == 0) {
   3509         // Regular logical right shift of a word by a fixed number of
   3510         // bits instruction. RS field is always equal to 0.
   3511         // Sign-extend the 64-bit result.
   3512         alu_out = static_cast<int64_t>(rt_u() >> sa());
   3513       } else if (rs_reg() == 1) {
   3514         // Logical right-rotate of a word by a fixed number of bits. This
   3515         // is special case of SRL instruction, added in MIPS32 Release 2.
   3516         // RS field is equal to 00001.
   3517         alu_out = static_cast<int64_t>(base::bits::RotateRight64(rt_u(), sa()));
   3518       } else {
   3519         UNREACHABLE();
   3520       }
   3521       SetResult(rd_reg(), alu_out);
   3522       break;
   3523     case DSRL32:
   3524       if (rs_reg() == 0) {
   3525         // Regular logical right shift of a word by a fixed number of
   3526         // bits instruction. RS field is always equal to 0.
   3527         // Sign-extend the 64-bit result.
   3528         alu_out = static_cast<int64_t>(rt_u() >> sa() >> 32);
   3529       } else if (rs_reg() == 1) {
   3530         // Logical right-rotate of a word by a fixed number of bits. This
   3531         // is special case of SRL instruction, added in MIPS32 Release 2.
   3532         // RS field is equal to 00001.
   3533         alu_out =
   3534             static_cast<int64_t>(base::bits::RotateRight64(rt_u(), sa() + 32));
   3535       } else {
   3536         UNREACHABLE();
   3537       }
   3538       SetResult(rd_reg(), alu_out);
   3539       break;
   3540     case SRA:
   3541       SetResult(rd_reg(), (int32_t)rt() >> sa());
   3542       break;
   3543     case DSRA:
   3544       SetResult(rd_reg(), rt() >> sa());
   3545       break;
   3546     case DSRA32:
   3547       SetResult(rd_reg(), rt() >> sa() >> 32);
   3548       break;
   3549     case SLLV:
   3550       SetResult(rd_reg(), (int32_t)rt() << rs());
   3551       break;
   3552     case DSLLV:
   3553       SetResult(rd_reg(), rt() << rs());
   3554       break;
   3555     case SRLV:
   3556       if (sa() == 0) {
   3557         // Regular logical right-shift of a word by a variable number of
   3558         // bits instruction. SA field is always equal to 0.
   3559         alu_out = static_cast<int32_t>((uint32_t)rt_u() >> rs());
   3560       } else {
   3561         // Logical right-rotate of a word by a variable number of bits.
   3562         // This is special case od SRLV instruction, added in MIPS32
   3563         // Release 2. SA field is equal to 00001.
   3564         alu_out = static_cast<int32_t>(
   3565             base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()),
   3566                                       static_cast<const uint32_t>(rs_u())));
   3567       }
   3568       SetResult(rd_reg(), alu_out);
   3569       break;
   3570     case DSRLV:
   3571       if (sa() == 0) {
   3572         // Regular logical right-shift of a word by a variable number of
   3573         // bits instruction. SA field is always equal to 0.
   3574         alu_out = static_cast<int64_t>(rt_u() >> rs());
   3575       } else {
   3576         // Logical right-rotate of a word by a variable number of bits.
   3577         // This is special case od SRLV instruction, added in MIPS32
   3578         // Release 2. SA field is equal to 00001.
   3579         alu_out =
   3580             static_cast<int64_t>(base::bits::RotateRight64(rt_u(), rs_u()));
   3581       }
   3582       SetResult(rd_reg(), alu_out);
   3583       break;
   3584     case SRAV:
   3585       SetResult(rd_reg(), (int32_t)rt() >> rs());
   3586       break;
   3587     case DSRAV:
   3588       SetResult(rd_reg(), rt() >> rs());
   3589       break;
   3590     case LSA: {
   3591       DCHECK(kArchVariant == kMips64r6);
   3592       int8_t sa = lsa_sa() + 1;
   3593       int32_t _rt = static_cast<int32_t>(rt());
   3594       int32_t _rs = static_cast<int32_t>(rs());
   3595       int32_t res = _rs << sa;
   3596       res += _rt;
   3597       SetResult(rd_reg(), static_cast<int64_t>(res));
   3598       break;
   3599     }
   3600     case DLSA:
   3601       DCHECK(kArchVariant == kMips64r6);
   3602       SetResult(rd_reg(), (rs() << (lsa_sa() + 1)) + rt());
   3603       break;
   3604     case MFHI:  // MFHI == CLZ on R6.
   3605       if (kArchVariant != kMips64r6) {
   3606         DCHECK(sa() == 0);
   3607         alu_out = get_register(HI);
   3608       } else {
   3609         // MIPS spec: If no bits were set in GPR rs(), the result written to
   3610         // GPR rd() is 32.
   3611         DCHECK(sa() == 1);
   3612         alu_out = base::bits::CountLeadingZeros32(static_cast<int32_t>(rs_u()));
   3613       }
   3614       SetResult(rd_reg(), alu_out);
   3615       break;
   3616     case MFLO:  // MFLO == DCLZ on R6.
   3617       if (kArchVariant != kMips64r6) {
   3618         DCHECK(sa() == 0);
   3619         alu_out = get_register(LO);
   3620       } else {
   3621         // MIPS spec: If no bits were set in GPR rs(), the result written to
   3622         // GPR rd() is 64.
   3623         DCHECK(sa() == 1);
   3624         alu_out = base::bits::CountLeadingZeros64(static_cast<int64_t>(rs_u()));
   3625       }
   3626       SetResult(rd_reg(), alu_out);
   3627       break;
   3628     // Instructions using HI and LO registers.
   3629     case MULT: {  // MULT == D_MUL_MUH.
   3630       int32_t rs_lo = static_cast<int32_t>(rs());
   3631       int32_t rt_lo = static_cast<int32_t>(rt());
   3632       i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo);
   3633       if (kArchVariant != kMips64r6) {
   3634         set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
   3635         set_register(HI, static_cast<int32_t>(i64hilo >> 32));
   3636       } else {
   3637         switch (sa()) {
   3638           case MUL_OP:
   3639             set_register(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff));
   3640             break;
   3641           case MUH_OP:
   3642             set_register(rd_reg(), static_cast<int32_t>(i64hilo >> 32));
   3643             break;
   3644           default:
   3645             UNIMPLEMENTED_MIPS();
   3646             break;
   3647         }
   3648       }
   3649       break;
   3650     }
   3651     case MULTU:
   3652       u64hilo = static_cast<uint64_t>(rs_u() & 0xffffffff) *
   3653                 static_cast<uint64_t>(rt_u() & 0xffffffff);
   3654       if (kArchVariant != kMips64r6) {
   3655         set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
   3656         set_register(HI, static_cast<int32_t>(u64hilo >> 32));
   3657       } else {
   3658         switch (sa()) {
   3659           case MUL_OP:
   3660             set_register(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff));
   3661             break;
   3662           case MUH_OP:
   3663             set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32));
   3664             break;
   3665           default:
   3666             UNIMPLEMENTED_MIPS();
   3667             break;
   3668         }
   3669       }
   3670       break;
   3671     case DMULT:  // DMULT == D_MUL_MUH.
   3672       if (kArchVariant != kMips64r6) {
   3673         set_register(LO, rs() * rt());
   3674         set_register(HI, MultiplyHighSigned(rs(), rt()));
   3675       } else {
   3676         switch (sa()) {
   3677           case MUL_OP:
   3678             set_register(rd_reg(), rs() * rt());
   3679             break;
   3680           case MUH_OP:
   3681             set_register(rd_reg(), MultiplyHighSigned(rs(), rt()));
   3682             break;
   3683           default:
   3684             UNIMPLEMENTED_MIPS();
   3685             break;
   3686         }
   3687       }
   3688       break;
   3689     case DMULTU:
   3690       UNIMPLEMENTED_MIPS();
   3691       break;
   3692     case DIV:
   3693     case DDIV: {
   3694       const int64_t int_min_value =
   3695           instr_.FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN;
   3696       switch (kArchVariant) {
   3697         case kMips64r2:
   3698           // Divide by zero and overflow was not checked in the
   3699           // configuration step - div and divu do not raise exceptions. On
   3700           // division by 0 the result will be UNPREDICTABLE. On overflow
   3701           // (INT_MIN/-1), return INT_MIN which is what the hardware does.
   3702           if (rs() == int_min_value && rt() == -1) {
   3703             set_register(LO, int_min_value);
   3704             set_register(HI, 0);
   3705           } else if (rt() != 0) {
   3706             set_register(LO, rs() / rt());
   3707             set_register(HI, rs() % rt());
   3708           }
   3709           break;
   3710         case kMips64r6:
   3711           switch (sa()) {
   3712             case DIV_OP:
   3713               if (rs() == int_min_value && rt() == -1) {
   3714                 set_register(rd_reg(), int_min_value);
   3715               } else if (rt() != 0) {
   3716                 set_register(rd_reg(), rs() / rt());
   3717               }
   3718               break;
   3719             case MOD_OP:
   3720               if (rs() == int_min_value && rt() == -1) {
   3721                 set_register(rd_reg(), 0);
   3722               } else if (rt() != 0) {
   3723                 set_register(rd_reg(), rs() % rt());
   3724               }
   3725               break;
   3726             default:
   3727               UNIMPLEMENTED_MIPS();
   3728               break;
   3729           }
   3730           break;
   3731         default:
   3732           break;
   3733       }
   3734       break;
   3735     }
   3736     case DIVU:
   3737       switch (kArchVariant) {
   3738         case kMips64r6: {
   3739           uint32_t rt_u_32 = static_cast<uint32_t>(rt_u());
   3740           uint32_t rs_u_32 = static_cast<uint32_t>(rs_u());
   3741           switch (sa()) {
   3742             case DIV_OP:
   3743               if (rt_u_32 != 0) {
   3744                 set_register(rd_reg(), rs_u_32 / rt_u_32);
   3745               }
   3746               break;
   3747             case MOD_OP:
   3748               if (rt_u() != 0) {
   3749                 set_register(rd_reg(), rs_u_32 % rt_u_32);
   3750               }
   3751               break;
   3752             default:
   3753               UNIMPLEMENTED_MIPS();
   3754               break;
   3755           }
   3756         } break;
   3757         default: {
   3758           if (rt_u() != 0) {
   3759             uint32_t rt_u_32 = static_cast<uint32_t>(rt_u());
   3760             uint32_t rs_u_32 = static_cast<uint32_t>(rs_u());
   3761             set_register(LO, rs_u_32 / rt_u_32);
   3762             set_register(HI, rs_u_32 % rt_u_32);
   3763           }
   3764         }
   3765       }
   3766       break;
   3767     case DDIVU:
   3768       switch (kArchVariant) {
   3769         case kMips64r6: {
   3770           switch (instr_.SaValue()) {
   3771             case DIV_OP:
   3772               if (rt_u() != 0) {
   3773                 set_register(rd_reg(), rs_u() / rt_u());
   3774               }
   3775               break;
   3776             case MOD_OP:
   3777               if (rt_u() != 0) {
   3778                 set_register(rd_reg(), rs_u() % rt_u());
   3779               }
   3780               break;
   3781             default:
   3782               UNIMPLEMENTED_MIPS();
   3783               break;
   3784           }
   3785         } break;
   3786         default: {
   3787           if (rt_u() != 0) {
   3788             set_register(LO, rs_u() / rt_u());
   3789             set_register(HI, rs_u() % rt_u());
   3790           }
   3791         }
   3792       }
   3793       break;
   3794     case ADD:
   3795     case DADD:
   3796       if (HaveSameSign(rs(), rt())) {
   3797         if (rs() > 0) {
   3798           if (rs() > (Registers::kMaxValue - rt())) {
   3799             SignalException(kIntegerOverflow);
   3800           }
   3801         } else if (rs() < 0) {
   3802           if (rs() < (Registers::kMinValue - rt())) {
   3803             SignalException(kIntegerUnderflow);
   3804           }
   3805         }
   3806       }
   3807       SetResult(rd_reg(), rs() + rt());
   3808       break;
   3809     case ADDU: {
   3810       int32_t alu32_out = static_cast<int32_t>(rs() + rt());
   3811       // Sign-extend result of 32bit operation into 64bit register.
   3812       SetResult(rd_reg(), static_cast<int64_t>(alu32_out));
   3813       break;
   3814     }
   3815     case DADDU:
   3816       SetResult(rd_reg(), rs() + rt());
   3817       break;
   3818     case SUB:
   3819     case DSUB:
   3820       if (!HaveSameSign(rs(), rt())) {
   3821         if (rs() > 0) {
   3822           if (rs() > (Registers::kMaxValue + rt())) {
   3823             SignalException(kIntegerOverflow);
   3824           }
   3825         } else if (rs() < 0) {
   3826           if (rs() < (Registers::kMinValue + rt())) {
   3827             SignalException(kIntegerUnderflow);
   3828           }
   3829         }
   3830       }
   3831       SetResult(rd_reg(), rs() - rt());
   3832       break;
   3833     case SUBU: {
   3834       int32_t alu32_out = static_cast<int32_t>(rs() - rt());
   3835       // Sign-extend result of 32bit operation into 64bit register.
   3836       SetResult(rd_reg(), static_cast<int64_t>(alu32_out));
   3837       break;
   3838     }
   3839     case DSUBU:
   3840       SetResult(rd_reg(), rs() - rt());
   3841       break;
   3842     case AND:
   3843       SetResult(rd_reg(), rs() & rt());
   3844       break;
   3845     case OR:
   3846       SetResult(rd_reg(), rs() | rt());
   3847       break;
   3848     case XOR:
   3849       SetResult(rd_reg(), rs() ^ rt());
   3850       break;
   3851     case NOR:
   3852       SetResult(rd_reg(), ~(rs() | rt()));
   3853       break;
   3854     case SLT:
   3855       SetResult(rd_reg(), rs() < rt() ? 1 : 0);
   3856       break;
   3857     case SLTU:
   3858       SetResult(rd_reg(), rs_u() < rt_u() ? 1 : 0);
   3859       break;
   3860     // Break and trap instructions.
   3861     case BREAK:
   3862       do_interrupt = true;
   3863       break;
   3864     case TGE:
   3865       do_interrupt = rs() >= rt();
   3866       break;
   3867     case TGEU:
   3868       do_interrupt = rs_u() >= rt_u();
   3869       break;
   3870     case TLT:
   3871       do_interrupt = rs() < rt();
   3872       break;
   3873     case TLTU:
   3874       do_interrupt = rs_u() < rt_u();
   3875       break;
   3876     case TEQ:
   3877       do_interrupt = rs() == rt();
   3878       break;
   3879     case TNE:
   3880       do_interrupt = rs() != rt();
   3881       break;
   3882     case SYNC:
   3883       // TODO(palfia): Ignore sync instruction for now.
   3884       break;
   3885     // Conditional moves.
   3886     case MOVN:
   3887       if (rt()) {
   3888         SetResult(rd_reg(), rs());
   3889       }
   3890       break;
   3891     case MOVCI: {
   3892       uint32_t cc = instr_.FBccValue();
   3893       uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
   3894       if (instr_.Bit(16)) {  // Read Tf bit.
   3895         if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
   3896       } else {
   3897         if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
   3898       }
   3899       break;
   3900     }
   3901     case MOVZ:
   3902       if (!rt()) {
   3903         SetResult(rd_reg(), rs());
   3904       }
   3905       break;
   3906     default:
   3907       UNREACHABLE();
   3908   }
   3909   if (do_interrupt) {
   3910     SoftwareInterrupt();
   3911   }
   3912 }
   3913 
   3914 
   3915 void Simulator::DecodeTypeRegisterSPECIAL2() {
   3916   int64_t alu_out;
   3917   switch (instr_.FunctionFieldRaw()) {
   3918     case MUL:
   3919       alu_out = static_cast<int32_t>(rs_u()) * static_cast<int32_t>(rt_u());
   3920       SetResult(rd_reg(), alu_out);
   3921       // HI and LO are UNPREDICTABLE after the operation.
   3922       set_register(LO, Unpredictable);
   3923       set_register(HI, Unpredictable);
   3924       break;
   3925     case CLZ:
   3926       // MIPS32 spec: If no bits were set in GPR rs(), the result written to
   3927       // GPR rd is 32.
   3928       alu_out = base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u()));
   3929       SetResult(rd_reg(), alu_out);
   3930       break;
   3931     case DCLZ:
   3932       // MIPS64 spec: If no bits were set in GPR rs(), the result written to
   3933       // GPR rd is 64.
   3934       alu_out = base::bits::CountLeadingZeros64(static_cast<uint64_t>(rs_u()));
   3935       SetResult(rd_reg(), alu_out);
   3936       break;
   3937     default:
   3938       alu_out = 0x12345678;
   3939       UNREACHABLE();
   3940   }
   3941 }
   3942 
   3943 
   3944 void Simulator::DecodeTypeRegisterSPECIAL3() {
   3945   int64_t alu_out;
   3946   switch (instr_.FunctionFieldRaw()) {
   3947     case INS: {  // Mips64r2 instruction.
   3948       // Interpret rd field as 5-bit msb of insert.
   3949       uint16_t msb = rd_reg();
   3950       // Interpret sa field as 5-bit lsb of insert.
   3951       uint16_t lsb = sa();
   3952       uint16_t size = msb - lsb + 1;
   3953       uint64_t mask = (1ULL << size) - 1;
   3954       alu_out = static_cast<int32_t>((rt_u() & ~(mask << lsb)) |
   3955                                      ((rs_u() & mask) << lsb));
   3956       SetResult(rt_reg(), alu_out);
   3957       break;
   3958     }
   3959     case DINS: {  // Mips64r2 instruction.
   3960       // Interpret rd field as 5-bit msb of insert.
   3961       uint16_t msb = rd_reg();
   3962       // Interpret sa field as 5-bit lsb of insert.
   3963       uint16_t lsb = sa();
   3964       uint16_t size = msb - lsb + 1;
   3965       uint64_t mask = (1ULL << size) - 1;
   3966       alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb);
   3967       SetResult(rt_reg(), alu_out);
   3968       break;
   3969     }
   3970     case EXT: {  // Mips64r2 instruction.
   3971       // Interpret rd field as 5-bit msb of extract.
   3972       uint16_t msb = rd_reg();
   3973       // Interpret sa field as 5-bit lsb of extract.
   3974       uint16_t lsb = sa();
   3975       uint16_t size = msb + 1;
   3976       uint64_t mask = (1ULL << size) - 1;
   3977       alu_out = static_cast<int32_t>((rs_u() & (mask << lsb)) >> lsb);
   3978       SetResult(rt_reg(), alu_out);
   3979       break;
   3980     }
   3981     case DEXT: {  // Mips64r2 instruction.
   3982       // Interpret rd field as 5-bit msb of extract.
   3983       uint16_t msb = rd_reg();
   3984       // Interpret sa field as 5-bit lsb of extract.
   3985       uint16_t lsb = sa();
   3986       uint16_t size = msb + 1;
   3987       uint64_t mask = (1ULL << size) - 1;
   3988       alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
   3989       SetResult(rt_reg(), alu_out);
   3990       break;
   3991     }
   3992     case DEXTM: {
   3993       // Interpret rd field as 5-bit msb of extract.
   3994       uint16_t msb = rd_reg();
   3995       // Interpret sa field as 5-bit lsb of extract.
   3996       uint16_t lsb = sa();
   3997       uint16_t size = msb + 33;
   3998       uint64_t mask = (1ULL << size) - 1;
   3999       alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
   4000       SetResult(rt_reg(), alu_out);
   4001       break;
   4002     }
   4003     case DEXTU: {
   4004       // Interpret rd field as 5-bit msb of extract.
   4005       uint16_t msb = rd_reg();
   4006       // Interpret sa field as 5-bit lsb of extract.
   4007       uint16_t lsb = sa() + 32;
   4008       uint16_t size = msb + 1;
   4009       uint64_t mask = (1ULL << size) - 1;
   4010       alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
   4011       SetResult(rt_reg(), alu_out);
   4012       break;
   4013     }
   4014     case BSHFL: {
   4015       int32_t sa = instr_.SaFieldRaw() >> kSaShift;
   4016       switch (sa) {
   4017         case BITSWAP: {
   4018           uint32_t input = static_cast<uint32_t>(rt());
   4019           uint32_t output = 0;
   4020           uint8_t i_byte, o_byte;
   4021 
   4022           // Reverse the bit in byte for each individual byte
   4023           for (int i = 0; i < 4; i++) {
   4024             output = output >> 8;
   4025             i_byte = input & 0xff;
   4026 
   4027             // Fast way to reverse bits in byte
   4028             // Devised by Sean Anderson, July 13, 2001
   4029             o_byte = static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
   4030                                            (i_byte * 0x8020LU & 0x88440LU)) *
   4031                                               0x10101LU >>
   4032                                           16);
   4033 
   4034             output = output | (static_cast<uint32_t>(o_byte << 24));
   4035             input = input >> 8;
   4036           }
   4037 
   4038           alu_out = static_cast<int64_t>(static_cast<int32_t>(output));
   4039           break;
   4040         }
   4041         case SEB: {
   4042           uint8_t input = static_cast<uint8_t>(rt());
   4043           uint32_t output = input;
   4044           uint32_t mask = 0x00000080;
   4045 
   4046           // Extending sign
   4047           if (mask & input) {
   4048             output |= 0xFFFFFF00;
   4049           }
   4050 
   4051           alu_out = static_cast<int32_t>(output);
   4052           break;
   4053         }
   4054         case SEH: {
   4055           uint16_t input = static_cast<uint16_t>(rt());
   4056           uint32_t output = input;
   4057           uint32_t mask = 0x00008000;
   4058 
   4059           // Extending sign
   4060           if (mask & input) {
   4061             output |= 0xFFFF0000;
   4062           }
   4063 
   4064           alu_out = static_cast<int32_t>(output);
   4065           break;
   4066         }
   4067         case WSBH: {
   4068           uint32_t input = static_cast<uint32_t>(rt());
   4069           uint64_t output = 0;
   4070 
   4071           uint32_t mask = 0xFF000000;
   4072           for (int i = 0; i < 4; i++) {
   4073             uint32_t tmp = mask & input;
   4074             if (i % 2 == 0) {
   4075               tmp = tmp >> 8;
   4076             } else {
   4077               tmp = tmp << 8;
   4078             }
   4079             output = output | tmp;
   4080             mask = mask >> 8;
   4081           }
   4082           mask = 0x80000000;
   4083 
   4084           // Extending sign
   4085           if (mask & output) {
   4086             output |= 0xFFFFFFFF00000000;
   4087           }
   4088 
   4089           alu_out = static_cast<int64_t>(output);
   4090           break;
   4091         }
   4092         default: {
   4093           const uint8_t bp2 = instr_.Bp2Value();
   4094           sa >>= kBp2Bits;
   4095           switch (sa) {
   4096             case ALIGN: {
   4097               if (bp2 == 0) {
   4098                 alu_out = static_cast<int32_t>(rt());
   4099               } else {
   4100                 uint64_t rt_hi = rt() << (8 * bp2);
   4101                 uint64_t rs_lo = rs() >> (8 * (4 - bp2));
   4102                 alu_out = static_cast<int32_t>(rt_hi | rs_lo);
   4103               }
   4104               break;
   4105             }
   4106             default:
   4107               alu_out = 0x12345678;
   4108               UNREACHABLE();
   4109               break;
   4110           }
   4111           break;
   4112         }
   4113       }
   4114       SetResult(rd_reg(), alu_out);
   4115       break;
   4116     }
   4117     case DBSHFL: {
   4118       int32_t sa = instr_.SaFieldRaw() >> kSaShift;
   4119       switch (sa) {
   4120         case DBITSWAP: {
   4121           switch (sa) {
   4122             case DBITSWAP_SA: {  // Mips64r6
   4123               uint64_t input = static_cast<uint64_t>(rt());
   4124               uint64_t output = 0;
   4125               uint8_t i_byte, o_byte;
   4126 
   4127               // Reverse the bit in byte for each individual byte
   4128               for (int i = 0; i < 8; i++) {
   4129                 output = output >> 8;
   4130                 i_byte = input & 0xff;
   4131 
   4132                 // Fast way to reverse bits in byte
   4133                 // Devised by Sean Anderson, July 13, 2001
   4134                 o_byte =
   4135                     static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) |
   4136                                           (i_byte * 0x8020LU & 0x88440LU)) *
   4137                                              0x10101LU >>
   4138                                          16);
   4139 
   4140                 output = output | ((static_cast<uint64_t>(o_byte) << 56));
   4141                 input = input >> 8;
   4142               }
   4143 
   4144               alu_out = static_cast<int64_t>(output);
   4145               break;
   4146             }
   4147           }
   4148           break;
   4149         }
   4150         case DSBH: {
   4151           uint64_t input = static_cast<uint64_t>(rt());
   4152           uint64_t output = 0;
   4153 
   4154           uint64_t mask = 0xFF00000000000000;
   4155           for (int i = 0; i < 8; i++) {
   4156             uint64_t tmp = mask & input;
   4157             if (i % 2 == 0)
   4158               tmp = tmp >> 8;
   4159             else
   4160               tmp = tmp << 8;
   4161 
   4162             output = output | tmp;
   4163             mask = mask >> 8;
   4164           }
   4165 
   4166           alu_out = static_cast<int64_t>(output);
   4167           break;
   4168         }
   4169         case DSHD: {
   4170           uint64_t input = static_cast<uint64_t>(rt());
   4171           uint64_t output = 0;
   4172 
   4173           uint64_t mask = 0xFFFF000000000000;
   4174           for (int i = 0; i < 4; i++) {
   4175             uint64_t tmp = mask & input;
   4176             if (i == 0)
   4177               tmp = tmp >> 48;
   4178             else if (i == 1)
   4179               tmp = tmp >> 16;
   4180             else if (i == 2)
   4181               tmp = tmp << 16;
   4182             else
   4183               tmp = tmp << 48;
   4184             output = output | tmp;
   4185             mask = mask >> 16;
   4186           }
   4187 
   4188           alu_out = static_cast<int64_t>(output);
   4189           break;
   4190         }
   4191         default: {
   4192           const uint8_t bp3 = instr_.Bp3Value();
   4193           sa >>= kBp3Bits;
   4194           switch (sa) {
   4195             case DALIGN: {
   4196               if (bp3 == 0) {
   4197                 alu_out = static_cast<int64_t>(rt());
   4198               } else {
   4199                 uint64_t rt_hi = rt() << (8 * bp3);
   4200                 uint64_t rs_lo = rs() >> (8 * (8 - bp3));
   4201                 alu_out = static_cast<int64_t>(rt_hi | rs_lo);
   4202               }
   4203               break;
   4204             }
   4205             default:
   4206               alu_out = 0x12345678;
   4207               UNREACHABLE();
   4208               break;
   4209           }
   4210           break;
   4211         }
   4212       }
   4213       SetResult(rd_reg(), alu_out);
   4214       break;
   4215     }
   4216     default:
   4217       UNREACHABLE();
   4218   }
   4219 }
   4220 
   4221 void Simulator::DecodeTypeRegister() {
   4222   // ---------- Execution.
   4223   switch (instr_.OpcodeFieldRaw()) {
   4224     case COP1:
   4225       DecodeTypeRegisterCOP1();
   4226       break;
   4227     case COP1X:
   4228       DecodeTypeRegisterCOP1X();
   4229       break;
   4230     case SPECIAL:
   4231       DecodeTypeRegisterSPECIAL();
   4232       break;
   4233     case SPECIAL2:
   4234       DecodeTypeRegisterSPECIAL2();
   4235       break;
   4236     case SPECIAL3:
   4237       DecodeTypeRegisterSPECIAL3();
   4238       break;
   4239     // Unimplemented opcodes raised an error in the configuration step before,
   4240     // so we can use the default here to set the destination register in common
   4241     // cases.
   4242     default:
   4243       UNREACHABLE();
   4244   }
   4245 }
   4246 
   4247 
   4248 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc).
   4249 void Simulator::DecodeTypeImmediate() {
   4250   // Instruction fields.
   4251   Opcode op = instr_.OpcodeFieldRaw();
   4252   int32_t rs_reg = instr_.RsValue();
   4253   int64_t rs = get_register(instr_.RsValue());
   4254   uint64_t rs_u = static_cast<uint64_t>(rs);
   4255   int32_t rt_reg = instr_.RtValue();  // Destination register.
   4256   int64_t rt = get_register(rt_reg);
   4257   int16_t imm16 = instr_.Imm16Value();
   4258   int32_t imm18 = instr_.Imm18Value();
   4259 
   4260   int32_t ft_reg = instr_.FtValue();  // Destination register.
   4261 
   4262   // Zero extended immediate.
   4263   uint64_t oe_imm16 = 0xffff & imm16;
   4264   // Sign extended immediate.
   4265   int64_t se_imm16 = imm16;
   4266   int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0);
   4267 
   4268   // Next pc.
   4269   int64_t next_pc = bad_ra;
   4270 
   4271   // Used for conditional branch instructions.
   4272   bool execute_branch_delay_instruction = false;
   4273 
   4274   // Used for arithmetic instructions.
   4275   int64_t alu_out = 0;
   4276 
   4277   // Used for memory instructions.
   4278   int64_t addr = 0x0;
   4279   // Alignment for 32-bit integers used in LWL, LWR, etc.
   4280   const int kInt32AlignmentMask = sizeof(uint32_t) - 1;
   4281   // Alignment for 64-bit integers used in LDL, LDR, etc.
   4282   const int kInt64AlignmentMask = sizeof(uint64_t) - 1;
   4283 
   4284   // Branch instructions common part.
   4285   auto BranchAndLinkHelper =
   4286       [this, &next_pc, &execute_branch_delay_instruction](bool do_branch) {
   4287         execute_branch_delay_instruction = true;
   4288         int64_t current_pc = get_pc();
   4289         if (do_branch) {
   4290           int16_t imm16 = instr_.Imm16Value();
   4291           next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
   4292           set_register(31, current_pc + 2 * Instruction::kInstrSize);
   4293         } else {
   4294           next_pc = current_pc + 2 * Instruction::kInstrSize;
   4295         }
   4296       };
   4297 
   4298   auto BranchHelper = [this, &next_pc,
   4299                        &execute_branch_delay_instruction](bool do_branch) {
   4300     execute_branch_delay_instruction = true;
   4301     int64_t current_pc = get_pc();
   4302     if (do_branch) {
   4303       int16_t imm16 = instr_.Imm16Value();
   4304       next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
   4305     } else {
   4306       next_pc = current_pc + 2 * Instruction::kInstrSize;
   4307     }
   4308   };
   4309 
   4310   auto BranchAndLinkCompactHelper = [this, &next_pc](bool do_branch, int bits) {
   4311     int64_t current_pc = get_pc();
   4312     CheckForbiddenSlot(current_pc);
   4313     if (do_branch) {
   4314       int32_t imm = instr_.ImmValue(bits);
   4315       imm <<= 32 - bits;
   4316       imm >>= 32 - bits;
   4317       next_pc = current_pc + (imm << 2) + Instruction::kInstrSize;
   4318       set_register(31, current_pc + Instruction::kInstrSize);
   4319     }
   4320   };
   4321 
   4322   auto BranchCompactHelper = [this, &next_pc](bool do_branch, int bits) {
   4323     int64_t current_pc = get_pc();
   4324     CheckForbiddenSlot(current_pc);
   4325     if (do_branch) {
   4326       int32_t imm = instr_.ImmValue(bits);
   4327       imm <<= 32 - bits;
   4328       imm >>= 32 - bits;
   4329       next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize;
   4330     }
   4331   };
   4332 
   4333   switch (op) {
   4334     // ------------- COP1. Coprocessor instructions.
   4335     case COP1:
   4336       switch (instr_.RsFieldRaw()) {
   4337         case BC1: {  // Branch on coprocessor condition.
   4338           uint32_t cc = instr_.FBccValue();
   4339           uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
   4340           uint32_t cc_value = test_fcsr_bit(fcsr_cc);
   4341           bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value;
   4342           BranchHelper(do_branch);
   4343           break;
   4344         }
   4345         case BC1EQZ:
   4346           BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
   4347           break;
   4348         case BC1NEZ:
   4349           BranchHelper(get_fpu_register(ft_reg) & 0x1);
   4350           break;
   4351         default:
   4352           UNREACHABLE();
   4353       }
   4354       break;
   4355     // ------------- REGIMM class.
   4356     case REGIMM:
   4357       switch (instr_.RtFieldRaw()) {
   4358         case BLTZ:
   4359           BranchHelper(rs < 0);
   4360           break;
   4361         case BGEZ:
   4362           BranchHelper(rs >= 0);
   4363           break;
   4364         case BLTZAL:
   4365           BranchAndLinkHelper(rs < 0);
   4366           break;
   4367         case BGEZAL:
   4368           BranchAndLinkHelper(rs >= 0);
   4369           break;
   4370         case DAHI:
   4371           SetResult(rs_reg, rs + (se_imm16 << 32));
   4372           break;
   4373         case DATI:
   4374           SetResult(rs_reg, rs + (se_imm16 << 48));
   4375           break;
   4376         default:
   4377           UNREACHABLE();
   4378       }
   4379       break;  // case REGIMM.
   4380     // ------------- Branch instructions.
   4381     // When comparing to zero, the encoding of rt field is always 0, so we don't
   4382     // need to replace rt with zero.
   4383     case BEQ:
   4384       BranchHelper(rs == rt);
   4385       break;
   4386     case BNE:
   4387       BranchHelper(rs != rt);
   4388       break;
   4389     case POP06:  // BLEZALC, BGEZALC, BGEUC, BLEZ (pre-r6)
   4390       if (kArchVariant == kMips64r6) {
   4391         if (rt_reg != 0) {
   4392           if (rs_reg == 0) {  // BLEZALC
   4393             BranchAndLinkCompactHelper(rt <= 0, 16);
   4394           } else {
   4395             if (rs_reg == rt_reg) {  // BGEZALC
   4396               BranchAndLinkCompactHelper(rt >= 0, 16);
   4397             } else {  // BGEUC
   4398               BranchCompactHelper(
   4399                   static_cast<uint64_t>(rs) >= static_cast<uint64_t>(rt), 16);
   4400             }
   4401           }
   4402         } else {  // BLEZ
   4403           BranchHelper(rs <= 0);
   4404         }
   4405       } else {  // BLEZ
   4406         BranchHelper(rs <= 0);
   4407       }
   4408       break;
   4409     case POP07:  // BGTZALC, BLTZALC, BLTUC, BGTZ (pre-r6)
   4410       if (kArchVariant == kMips64r6) {
   4411         if (rt_reg != 0) {
   4412           if (rs_reg == 0) {  // BGTZALC
   4413             BranchAndLinkCompactHelper(rt > 0, 16);
   4414           } else {
   4415             if (rt_reg == rs_reg) {  // BLTZALC
   4416               BranchAndLinkCompactHelper(rt < 0, 16);
   4417             } else {  // BLTUC
   4418               BranchCompactHelper(
   4419                   static_cast<uint64_t>(rs) < static_cast<uint64_t>(rt), 16);
   4420             }
   4421           }
   4422         } else {  // BGTZ
   4423           BranchHelper(rs > 0);
   4424         }
   4425       } else {  // BGTZ
   4426         BranchHelper(rs > 0);
   4427       }
   4428       break;
   4429     case POP26:  // BLEZC, BGEZC, BGEC/BLEC / BLEZL (pre-r6)
   4430       if (kArchVariant == kMips64r6) {
   4431         if (rt_reg != 0) {
   4432           if (rs_reg == 0) {  // BLEZC
   4433             BranchCompactHelper(rt <= 0, 16);
   4434           } else {
   4435             if (rs_reg == rt_reg) {  // BGEZC
   4436               BranchCompactHelper(rt >= 0, 16);
   4437             } else {  // BGEC/BLEC
   4438               BranchCompactHelper(rs >= rt, 16);
   4439             }
   4440           }
   4441         }
   4442       } else {  // BLEZL
   4443         BranchAndLinkHelper(rs <= 0);
   4444       }
   4445       break;
   4446     case POP27:  // BGTZC, BLTZC, BLTC/BGTC / BGTZL (pre-r6)
   4447       if (kArchVariant == kMips64r6) {
   4448         if (rt_reg != 0) {
   4449           if (rs_reg == 0) {  // BGTZC
   4450             BranchCompactHelper(rt > 0, 16);
   4451           } else {
   4452             if (rs_reg == rt_reg) {  // BLTZC
   4453               BranchCompactHelper(rt < 0, 16);
   4454             } else {  // BLTC/BGTC
   4455               BranchCompactHelper(rs < rt, 16);
   4456             }
   4457           }
   4458         }
   4459       } else {  // BGTZL
   4460         BranchAndLinkHelper(rs > 0);
   4461       }
   4462       break;
   4463     case POP66:           // BEQZC, JIC
   4464       if (rs_reg != 0) {  // BEQZC
   4465         BranchCompactHelper(rs == 0, 21);
   4466       } else {  // JIC
   4467         next_pc = rt + imm16;
   4468       }
   4469       break;
   4470     case POP76:           // BNEZC, JIALC
   4471       if (rs_reg != 0) {  // BNEZC
   4472         BranchCompactHelper(rs != 0, 21);
   4473       } else {  // JIALC
   4474         int64_t current_pc = get_pc();
   4475         set_register(31, current_pc + Instruction::kInstrSize);
   4476         next_pc = rt + imm16;
   4477       }
   4478       break;
   4479     case BC:
   4480       BranchCompactHelper(true, 26);
   4481       break;
   4482     case BALC:
   4483       BranchAndLinkCompactHelper(true, 26);
   4484       break;
   4485     case POP10:  // BOVC, BEQZALC, BEQC / ADDI (pre-r6)
   4486       if (kArchVariant == kMips64r6) {
   4487         if (rs_reg >= rt_reg) {  // BOVC
   4488           bool condition = !is_int32(rs) || !is_int32(rt) || !is_int32(rs + rt);
   4489           BranchCompactHelper(condition, 16);
   4490         } else {
   4491           if (rs_reg == 0) {  // BEQZALC
   4492             BranchAndLinkCompactHelper(rt == 0, 16);
   4493           } else {  // BEQC
   4494             BranchCompactHelper(rt == rs, 16);
   4495           }
   4496         }
   4497       } else {  // ADDI
   4498         if (HaveSameSign(rs, se_imm16)) {
   4499           if (rs > 0) {
   4500             if (rs <= Registers::kMaxValue - se_imm16) {
   4501               SignalException(kIntegerOverflow);
   4502             }
   4503           } else if (rs < 0) {
   4504             if (rs >= Registers::kMinValue - se_imm16) {
   4505               SignalException(kIntegerUnderflow);
   4506             }
   4507           }
   4508         }
   4509         SetResult(rt_reg, rs + se_imm16);
   4510       }
   4511       break;
   4512     case POP30:  // BNVC, BNEZALC, BNEC / DADDI (pre-r6)
   4513       if (kArchVariant == kMips64r6) {
   4514         if (rs_reg >= rt_reg) {  // BNVC
   4515           bool condition = is_int32(rs) && is_int32(rt) && is_int32(rs + rt);
   4516           BranchCompactHelper(condition, 16);
   4517         } else {
   4518           if (rs_reg == 0) {  // BNEZALC
   4519             BranchAndLinkCompactHelper(rt != 0, 16);
   4520           } else {  // BNEC
   4521             BranchCompactHelper(rt != rs, 16);
   4522           }
   4523         }
   4524       }
   4525       break;
   4526     // ------------- Arithmetic instructions.
   4527     case ADDIU: {
   4528       DCHECK(is_int32(rs));
   4529       int32_t alu32_out = static_cast<int32_t>(rs + se_imm16);
   4530       // Sign-extend result of 32bit operation into 64bit register.
   4531       SetResult(rt_reg, static_cast<int64_t>(alu32_out));
   4532       break;
   4533     }
   4534     case DADDIU:
   4535       SetResult(rt_reg, rs + se_imm16);
   4536       break;
   4537     case SLTI:
   4538       SetResult(rt_reg, rs < se_imm16 ? 1 : 0);
   4539       break;
   4540     case SLTIU:
   4541       SetResult(rt_reg, rs_u < static_cast<uint64_t>(se_imm16) ? 1 : 0);
   4542       break;
   4543     case ANDI:
   4544       SetResult(rt_reg, rs & oe_imm16);
   4545       break;
   4546     case ORI:
   4547       SetResult(rt_reg, rs | oe_imm16);
   4548       break;
   4549     case XORI:
   4550       SetResult(rt_reg, rs ^ oe_imm16);
   4551       break;
   4552     case LUI:
   4553       if (rs_reg != 0) {
   4554         // AUI instruction.
   4555         DCHECK(kArchVariant == kMips64r6);
   4556         int32_t alu32_out = static_cast<int32_t>(rs + (se_imm16 << 16));
   4557         SetResult(rt_reg, static_cast<int64_t>(alu32_out));
   4558       } else {
   4559         // LUI instruction.
   4560         int32_t alu32_out = static_cast<int32_t>(oe_imm16 << 16);
   4561         // Sign-extend result of 32bit operation into 64bit register.
   4562         SetResult(rt_reg, static_cast<int64_t>(alu32_out));
   4563       }
   4564       break;
   4565     case DAUI:
   4566       DCHECK(kArchVariant == kMips64r6);
   4567       DCHECK(rs_reg != 0);
   4568       SetResult(rt_reg, rs + (se_imm16 << 16));
   4569       break;
   4570     // ------------- Memory instructions.
   4571     case LB:
   4572       set_register(rt_reg, ReadB(rs + se_imm16));
   4573       break;
   4574     case LH:
   4575       set_register(rt_reg, ReadH(rs + se_imm16, instr_.instr()));
   4576       break;
   4577     case LWL: {
   4578       // al_offset is offset of the effective address within an aligned word.
   4579       uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
   4580       uint8_t byte_shift = kInt32AlignmentMask - al_offset;
   4581       uint32_t mask = (1 << byte_shift * 8) - 1;
   4582       addr = rs + se_imm16 - al_offset;
   4583       int32_t val = ReadW(addr, instr_.instr());
   4584       val <<= byte_shift * 8;
   4585       val |= rt & mask;
   4586       set_register(rt_reg, static_cast<int64_t>(val));
   4587       break;
   4588     }
   4589     case LW:
   4590       set_register(rt_reg, ReadW(rs + se_imm16, instr_.instr()));
   4591       break;
   4592     case LWU:
   4593       set_register(rt_reg, ReadWU(rs + se_imm16, instr_.instr()));
   4594       break;
   4595     case LD:
   4596       set_register(rt_reg, Read2W(rs + se_imm16, instr_.instr()));
   4597       break;
   4598     case LBU:
   4599       set_register(rt_reg, ReadBU(rs + se_imm16));
   4600       break;
   4601     case LHU:
   4602       set_register(rt_reg, ReadHU(rs + se_imm16, instr_.instr()));
   4603       break;
   4604     case LWR: {
   4605       // al_offset is offset of the effective address within an aligned word.
   4606       uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
   4607       uint8_t byte_shift = kInt32AlignmentMask - al_offset;
   4608       uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
   4609       addr = rs + se_imm16 - al_offset;
   4610       alu_out = ReadW(addr, instr_.instr());
   4611       alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
   4612       alu_out |= rt & mask;
   4613       set_register(rt_reg, alu_out);
   4614       break;
   4615     }
   4616     case LDL: {
   4617       // al_offset is offset of the effective address within an aligned word.
   4618       uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
   4619       uint8_t byte_shift = kInt64AlignmentMask - al_offset;
   4620       uint64_t mask = (1UL << byte_shift * 8) - 1;
   4621       addr = rs + se_imm16 - al_offset;
   4622       alu_out = Read2W(addr, instr_.instr());
   4623       alu_out <<= byte_shift * 8;
   4624       alu_out |= rt & mask;
   4625       set_register(rt_reg, alu_out);
   4626       break;
   4627     }
   4628     case LDR: {
   4629       // al_offset is offset of the effective address within an aligned word.
   4630       uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
   4631       uint8_t byte_shift = kInt64AlignmentMask - al_offset;
   4632       uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL;
   4633       addr = rs + se_imm16 - al_offset;
   4634       alu_out = Read2W(addr, instr_.instr());
   4635       alu_out = alu_out >> al_offset * 8;
   4636       alu_out |= rt & mask;
   4637       set_register(rt_reg, alu_out);
   4638       break;
   4639     }
   4640     case SB:
   4641       WriteB(rs + se_imm16, static_cast<int8_t>(rt));
   4642       break;
   4643     case SH:
   4644       WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr_.instr());
   4645       break;
   4646     case SWL: {
   4647       uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
   4648       uint8_t byte_shift = kInt32AlignmentMask - al_offset;
   4649       uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
   4650       addr = rs + se_imm16 - al_offset;
   4651       uint64_t mem_value = ReadW(addr, instr_.instr()) & mask;
   4652       mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
   4653       WriteW(addr, static_cast<int32_t>(mem_value), instr_.instr());
   4654       break;
   4655     }
   4656     case SW:
   4657       WriteW(rs + se_imm16, static_cast<int32_t>(rt), instr_.instr());
   4658       break;
   4659     case SD:
   4660       Write2W(rs + se_imm16, rt, instr_.instr());
   4661       break;
   4662     case SWR: {
   4663       uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
   4664       uint32_t mask = (1 << al_offset * 8) - 1;
   4665       addr = rs + se_imm16 - al_offset;
   4666       uint64_t mem_value = ReadW(addr, instr_.instr());
   4667       mem_value = (rt << al_offset * 8) | (mem_value & mask);
   4668       WriteW(addr, static_cast<int32_t>(mem_value), instr_.instr());
   4669       break;
   4670     }
   4671     case SDL: {
   4672       uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
   4673       uint8_t byte_shift = kInt64AlignmentMask - al_offset;
   4674       uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0;
   4675       addr = rs + se_imm16 - al_offset;
   4676       uint64_t mem_value = Read2W(addr, instr_.instr()) & mask;
   4677       mem_value |= rt >> byte_shift * 8;
   4678       Write2W(addr, mem_value, instr_.instr());
   4679       break;
   4680     }
   4681     case SDR: {
   4682       uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
   4683       uint64_t mask = (1UL << al_offset * 8) - 1;
   4684       addr = rs + se_imm16 - al_offset;
   4685       uint64_t mem_value = Read2W(addr, instr_.instr());
   4686       mem_value = (rt << al_offset * 8) | (mem_value & mask);
   4687       Write2W(addr, mem_value, instr_.instr());
   4688       break;
   4689     }
   4690     case LWC1:
   4691       set_fpu_register(ft_reg, kFPUInvalidResult);  // Trash upper 32 bits.
   4692       set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr()));
   4693       break;
   4694     case LDC1:
   4695       set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr()));
   4696       break;
   4697     case SWC1: {
   4698       int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg));
   4699       WriteW(rs + se_imm16, alu_out_32, instr_.instr());
   4700       break;
   4701     }
   4702     case SDC1:
   4703       WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr());
   4704       break;
   4705     // ------------- PC-Relative instructions.
   4706     case PCREL: {
   4707       // rt field: checking 5-bits.
   4708       int32_t imm21 = instr_.Imm21Value();
   4709       int64_t current_pc = get_pc();
   4710       uint8_t rt = (imm21 >> kImm16Bits);
   4711       switch (rt) {
   4712         case ALUIPC:
   4713           addr = current_pc + (se_imm16 << 16);
   4714           alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
   4715           break;
   4716         case AUIPC:
   4717           alu_out = current_pc + (se_imm16 << 16);
   4718           break;
   4719         default: {
   4720           int32_t imm19 = instr_.Imm19Value();
   4721           // rt field: checking the most significant 3-bits.
   4722           rt = (imm21 >> kImm18Bits);
   4723           switch (rt) {
   4724             case LDPC:
   4725               addr =
   4726                   (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3);
   4727               alu_out = Read2W(addr, instr_.instr());
   4728               break;
   4729             default: {
   4730               // rt field: checking the most significant 2-bits.
   4731               rt = (imm21 >> kImm19Bits);
   4732               switch (rt) {
   4733                 case LWUPC: {
   4734                   // Set sign.
   4735                   imm19 <<= (kOpcodeBits + kRsBits + 2);
   4736                   imm19 >>= (kOpcodeBits + kRsBits + 2);
   4737                   addr = current_pc + (imm19 << 2);
   4738                   uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
   4739                   alu_out = *ptr;
   4740                   break;
   4741                 }
   4742                 case LWPC: {
   4743                   // Set sign.
   4744                   imm19 <<= (kOpcodeBits + kRsBits + 2);
   4745                   imm19 >>= (kOpcodeBits + kRsBits + 2);
   4746                   addr = current_pc + (imm19 << 2);
   4747                   int32_t* ptr = reinterpret_cast<int32_t*>(addr);
   4748                   alu_out = *ptr;
   4749                   break;
   4750                 }
   4751                 case ADDIUPC: {
   4752                   int64_t se_imm19 =
   4753                       imm19 | ((imm19 & 0x40000) ? 0xfffffffffff80000 : 0);
   4754                   alu_out = current_pc + (se_imm19 << 2);
   4755                   break;
   4756                 }
   4757                 default:
   4758                   UNREACHABLE();
   4759                   break;
   4760               }
   4761               break;
   4762             }
   4763           }
   4764           break;
   4765         }
   4766       }
   4767       set_register(rs_reg, alu_out);
   4768       break;
   4769     }
   4770     default:
   4771       UNREACHABLE();
   4772   }
   4773 
   4774   if (execute_branch_delay_instruction) {
   4775     // Execute branch delay slot
   4776     // We don't check for end_sim_pc. First it should not be met as the current
   4777     // pc is valid. Secondly a jump should always execute its branch delay slot.
   4778     Instruction* branch_delay_instr =
   4779         reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize);
   4780     BranchDelayInstructionDecode(branch_delay_instr);
   4781   }
   4782 
   4783   // If needed update pc after the branch delay execution.
   4784   if (next_pc != bad_ra) {
   4785     set_pc(next_pc);
   4786   }
   4787 }
   4788 
   4789 
   4790 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
   4791 void Simulator::DecodeTypeJump() {
   4792   SimInstruction simInstr = instr_;
   4793   // Get current pc.
   4794   int64_t current_pc = get_pc();
   4795   // Get unchanged bits of pc.
   4796   int64_t pc_high_bits = current_pc & 0xfffffffff0000000;
   4797   // Next pc.
   4798   int64_t next_pc = pc_high_bits | (simInstr.Imm26Value() << 2);
   4799 
   4800   // Execute branch delay slot.
   4801   // We don't check for end_sim_pc. First it should not be met as the current pc
   4802   // is valid. Secondly a jump should always execute its branch delay slot.
   4803   Instruction* branch_delay_instr =
   4804       reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
   4805   BranchDelayInstructionDecode(branch_delay_instr);
   4806 
   4807   // Update pc and ra if necessary.
   4808   // Do this after the branch delay execution.
   4809   if (simInstr.IsLinkingInstruction()) {
   4810     set_register(31, current_pc + 2 * Instruction::kInstrSize);
   4811   }
   4812   set_pc(next_pc);
   4813   pc_modified_ = true;
   4814 }
   4815 
   4816 
   4817 // Executes the current instruction.
   4818 void Simulator::InstructionDecode(Instruction* instr) {
   4819   if (v8::internal::FLAG_check_icache) {
   4820     CheckICache(isolate_->simulator_i_cache(), instr);
   4821   }
   4822   pc_modified_ = false;
   4823 
   4824   v8::internal::EmbeddedVector<char, 256> buffer;
   4825 
   4826   if (::v8::internal::FLAG_trace_sim) {
   4827     SNPrintF(trace_buf_, " ");
   4828     disasm::NameConverter converter;
   4829     disasm::Disassembler dasm(converter);
   4830     // Use a reasonably large buffer.
   4831     dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
   4832   }
   4833 
   4834   instr_ = instr;
   4835   switch (instr_.InstructionType()) {
   4836     case Instruction::kRegisterType:
   4837       DecodeTypeRegister();
   4838       break;
   4839     case Instruction::kImmediateType:
   4840       DecodeTypeImmediate();
   4841       break;
   4842     case Instruction::kJumpType:
   4843       DecodeTypeJump();
   4844       break;
   4845     default:
   4846       UNSUPPORTED();
   4847   }
   4848 
   4849   if (::v8::internal::FLAG_trace_sim) {
   4850     PrintF("  0x%08" PRIxPTR "   %-44s   %s\n",
   4851            reinterpret_cast<intptr_t>(instr), buffer.start(),
   4852            trace_buf_.start());
   4853   }
   4854 
   4855   if (!pc_modified_) {
   4856     set_register(pc, reinterpret_cast<int64_t>(instr) +
   4857                  Instruction::kInstrSize);
   4858   }
   4859 }
   4860 
   4861 
   4862 
   4863 void Simulator::Execute() {
   4864   // Get the PC to simulate. Cannot use the accessor here as we need the
   4865   // raw PC value and not the one used as input to arithmetic instructions.
   4866   int64_t program_counter = get_pc();
   4867   if (::v8::internal::FLAG_stop_sim_at == 0) {
   4868     // Fast version of the dispatch loop without checking whether the simulator
   4869     // should be stopping at a particular executed instruction.
   4870     while (program_counter != end_sim_pc) {
   4871       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
   4872       icount_++;
   4873       InstructionDecode(instr);
   4874       program_counter = get_pc();
   4875     }
   4876   } else {
   4877     // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
   4878     // we reach the particular instuction count.
   4879     while (program_counter != end_sim_pc) {
   4880       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
   4881       icount_++;
   4882       if (icount_ == static_cast<int64_t>(::v8::internal::FLAG_stop_sim_at)) {
   4883         MipsDebugger dbg(this);
   4884         dbg.Debug();
   4885       } else {
   4886         InstructionDecode(instr);
   4887       }
   4888       program_counter = get_pc();
   4889     }
   4890   }
   4891 }
   4892 
   4893 
   4894 void Simulator::CallInternal(byte* entry) {
   4895   // Adjust JS-based stack limit to C-based stack limit.
   4896   isolate_->stack_guard()->AdjustStackLimitForSimulator();
   4897 
   4898   // Prepare to execute the code at entry.
   4899   set_register(pc, reinterpret_cast<int64_t>(entry));
   4900   // Put down marker for end of simulation. The simulator will stop simulation
   4901   // when the PC reaches this value. By saving the "end simulation" value into
   4902   // the LR the simulation stops when returning to this call point.
   4903   set_register(ra, end_sim_pc);
   4904 
   4905   // Remember the values of callee-saved registers.
   4906   // The code below assumes that r9 is not used as sb (static base) in
   4907   // simulator code and therefore is regarded as a callee-saved register.
   4908   int64_t s0_val = get_register(s0);
   4909   int64_t s1_val = get_register(s1);
   4910   int64_t s2_val = get_register(s2);
   4911   int64_t s3_val = get_register(s3);
   4912   int64_t s4_val = get_register(s4);
   4913   int64_t s5_val = get_register(s5);
   4914   int64_t s6_val = get_register(s6);
   4915   int64_t s7_val = get_register(s7);
   4916   int64_t gp_val = get_register(gp);
   4917   int64_t sp_val = get_register(sp);
   4918   int64_t fp_val = get_register(fp);
   4919 
   4920   // Set up the callee-saved registers with a known value. To be able to check
   4921   // that they are preserved properly across JS execution.
   4922   int64_t callee_saved_value = icount_;
   4923   set_register(s0, callee_saved_value);
   4924   set_register(s1, callee_saved_value);
   4925   set_register(s2, callee_saved_value);
   4926   set_register(s3, callee_saved_value);
   4927   set_register(s4, callee_saved_value);
   4928   set_register(s5, callee_saved_value);
   4929   set_register(s6, callee_saved_value);
   4930   set_register(s7, callee_saved_value);
   4931   set_register(gp, callee_saved_value);
   4932   set_register(fp, callee_saved_value);
   4933 
   4934   // Start the simulation.
   4935   Execute();
   4936 
   4937   // Check that the callee-saved registers have been preserved.
   4938   CHECK_EQ(callee_saved_value, get_register(s0));
   4939   CHECK_EQ(callee_saved_value, get_register(s1));
   4940   CHECK_EQ(callee_saved_value, get_register(s2));
   4941   CHECK_EQ(callee_saved_value, get_register(s3));
   4942   CHECK_EQ(callee_saved_value, get_register(s4));
   4943   CHECK_EQ(callee_saved_value, get_register(s5));
   4944   CHECK_EQ(callee_saved_value, get_register(s6));
   4945   CHECK_EQ(callee_saved_value, get_register(s7));
   4946   CHECK_EQ(callee_saved_value, get_register(gp));
   4947   CHECK_EQ(callee_saved_value, get_register(fp));
   4948 
   4949   // Restore callee-saved registers with the original value.
   4950   set_register(s0, s0_val);
   4951   set_register(s1, s1_val);
   4952   set_register(s2, s2_val);
   4953   set_register(s3, s3_val);
   4954   set_register(s4, s4_val);
   4955   set_register(s5, s5_val);
   4956   set_register(s6, s6_val);
   4957   set_register(s7, s7_val);
   4958   set_register(gp, gp_val);
   4959   set_register(sp, sp_val);
   4960   set_register(fp, fp_val);
   4961 }
   4962 
   4963 
   4964 int64_t Simulator::Call(byte* entry, int argument_count, ...) {
   4965   const int kRegisterPassedArguments = 8;
   4966   va_list parameters;
   4967   va_start(parameters, argument_count);
   4968   // Set up arguments.
   4969 
   4970   // First four arguments passed in registers in both ABI's.
   4971   DCHECK(argument_count >= 4);
   4972   set_register(a0, va_arg(parameters, int64_t));
   4973   set_register(a1, va_arg(parameters, int64_t));
   4974   set_register(a2, va_arg(parameters, int64_t));
   4975   set_register(a3, va_arg(parameters, int64_t));
   4976 
   4977   // Up to eight arguments passed in registers in N64 ABI.
   4978   // TODO(plind): N64 ABI calls these regs a4 - a7. Clarify this.
   4979   if (argument_count >= 5) set_register(a4, va_arg(parameters, int64_t));
   4980   if (argument_count >= 6) set_register(a5, va_arg(parameters, int64_t));
   4981   if (argument_count >= 7) set_register(a6, va_arg(parameters, int64_t));
   4982   if (argument_count >= 8) set_register(a7, va_arg(parameters, int64_t));
   4983 
   4984   // Remaining arguments passed on stack.
   4985   int64_t original_stack = get_register(sp);
   4986   // Compute position of stack on entry to generated code.
   4987   int stack_args_count = (argument_count > kRegisterPassedArguments) ?
   4988                          (argument_count - kRegisterPassedArguments) : 0;
   4989   int stack_args_size = stack_args_count * sizeof(int64_t) + kCArgsSlotsSize;
   4990   int64_t entry_stack = original_stack - stack_args_size;
   4991 
   4992   if (base::OS::ActivationFrameAlignment() != 0) {
   4993     entry_stack &= -base::OS::ActivationFrameAlignment();
   4994   }
   4995   // Store remaining arguments on stack, from low to high memory.
   4996   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
   4997   for (int i = kRegisterPassedArguments; i < argument_count; i++) {
   4998     int stack_index = i - kRegisterPassedArguments + kCArgSlotCount;
   4999     stack_argument[stack_index] = va_arg(parameters, int64_t);
   5000   }
   5001   va_end(parameters);
   5002   set_register(sp, entry_stack);
   5003 
   5004   CallInternal(entry);
   5005 
   5006   // Pop stack passed arguments.
   5007   CHECK_EQ(entry_stack, get_register(sp));
   5008   set_register(sp, original_stack);
   5009 
   5010   int64_t result = get_register(v0);
   5011   return result;
   5012 }
   5013 
   5014 
   5015 double Simulator::CallFP(byte* entry, double d0, double d1) {
   5016   if (!IsMipsSoftFloatABI) {
   5017     const FPURegister fparg2 = f13;
   5018     set_fpu_register_double(f12, d0);
   5019     set_fpu_register_double(fparg2, d1);
   5020   } else {
   5021     int buffer[2];
   5022     DCHECK(sizeof(buffer[0]) * 2 == sizeof(d0));
   5023     memcpy(buffer, &d0, sizeof(d0));
   5024     set_dw_register(a0, buffer);
   5025     memcpy(buffer, &d1, sizeof(d1));
   5026     set_dw_register(a2, buffer);
   5027   }
   5028   CallInternal(entry);
   5029   if (!IsMipsSoftFloatABI) {
   5030     return get_fpu_register_double(f0);
   5031   } else {
   5032     return get_double_from_register_pair(v0);
   5033   }
   5034 }
   5035 
   5036 
   5037 uintptr_t Simulator::PushAddress(uintptr_t address) {
   5038   int64_t new_sp = get_register(sp) - sizeof(uintptr_t);
   5039   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
   5040   *stack_slot = address;
   5041   set_register(sp, new_sp);
   5042   return new_sp;
   5043 }
   5044 
   5045 
   5046 uintptr_t Simulator::PopAddress() {
   5047   int64_t current_sp = get_register(sp);
   5048   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
   5049   uintptr_t address = *stack_slot;
   5050   set_register(sp, current_sp + sizeof(uintptr_t));
   5051   return address;
   5052 }
   5053 
   5054 
   5055 #undef UNSUPPORTED
   5056 }  // namespace internal
   5057 }  // namespace v8
   5058 
   5059 #endif  // USE_SIMULATOR
   5060 
   5061 #endif  // V8_TARGET_ARCH_MIPS64
   5062