Home | History | Annotate | Download | only in mips
      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 #include "src/v8.h"
     11 
     12 #if V8_TARGET_ARCH_MIPS
     13 
     14 #include "src/cpu.h"
     15 #include "src/disasm.h"
     16 #include "src/assembler.h"
     17 #include "src/globals.h"    // Need the BitCast.
     18 #include "src/mips/constants-mips.h"
     19 #include "src/mips/simulator-mips.h"
     20 
     21 
     22 // Only build the simulator if not compiling for real MIPS hardware.
     23 #if defined(USE_SIMULATOR)
     24 
     25 namespace v8 {
     26 namespace internal {
     27 
     28 // Utils functions.
     29 bool HaveSameSign(int32_t a, int32_t b) {
     30   return ((a ^ b) >= 0);
     31 }
     32 
     33 
     34 uint32_t get_fcsr_condition_bit(uint32_t cc) {
     35   if (cc == 0) {
     36     return 23;
     37   } else {
     38     return 24 + cc;
     39   }
     40 }
     41 
     42 
     43 // This macro provides a platform independent use of sscanf. The reason for
     44 // SScanF not being implemented in a platform independent was through
     45 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time
     46 // Library does not provide vsscanf.
     47 #define SScanF sscanf  // NOLINT
     48 
     49 // The MipsDebugger class is used by the simulator while debugging simulated
     50 // code.
     51 class MipsDebugger {
     52  public:
     53   explicit MipsDebugger(Simulator* sim) : sim_(sim) { }
     54   ~MipsDebugger();
     55 
     56   void Stop(Instruction* instr);
     57   void Debug();
     58   // Print all registers with a nice formatting.
     59   void PrintAllRegs();
     60   void PrintAllRegsIncludingFPU();
     61 
     62  private:
     63   // We set the breakpoint code to 0xfffff to easily recognize it.
     64   static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6;
     65   static const Instr kNopInstr =  0x0;
     66 
     67   Simulator* sim_;
     68 
     69   int32_t GetRegisterValue(int regnum);
     70   int32_t GetFPURegisterValueInt(int regnum);
     71   int64_t GetFPURegisterValueLong(int regnum);
     72   float GetFPURegisterValueFloat(int regnum);
     73   double GetFPURegisterValueDouble(int regnum);
     74   bool GetValue(const char* desc, int32_t* value);
     75 
     76   // Set or delete a breakpoint. Returns true if successful.
     77   bool SetBreakpoint(Instruction* breakpc);
     78   bool DeleteBreakpoint(Instruction* breakpc);
     79 
     80   // Undo and redo all breakpoints. This is needed to bracket disassembly and
     81   // execution to skip past breakpoints when run from the debugger.
     82   void UndoBreakpoints();
     83   void RedoBreakpoints();
     84 };
     85 
     86 
     87 MipsDebugger::~MipsDebugger() {
     88 }
     89 
     90 
     91 #ifdef GENERATED_CODE_COVERAGE
     92 static FILE* coverage_log = NULL;
     93 
     94 
     95 static void InitializeCoverage() {
     96   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
     97   if (file_name != NULL) {
     98     coverage_log = fopen(file_name, "aw+");
     99   }
    100 }
    101 
    102 
    103 void MipsDebugger::Stop(Instruction* instr) {
    104   // Get the stop code.
    105   uint32_t code = instr->Bits(25, 6);
    106   // Retrieve the encoded address, which comes just after this stop.
    107   char** msg_address =
    108     reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
    109   char* msg = *msg_address;
    110   ASSERT(msg != NULL);
    111 
    112   // Update this stop description.
    113   if (!watched_stops_[code].desc) {
    114     watched_stops_[code].desc = msg;
    115   }
    116 
    117   if (strlen(msg) > 0) {
    118     if (coverage_log != NULL) {
    119       fprintf(coverage_log, "%s\n", str);
    120       fflush(coverage_log);
    121     }
    122     // Overwrite the instruction and address with nops.
    123     instr->SetInstructionBits(kNopInstr);
    124     reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
    125   }
    126   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize);
    127 }
    128 
    129 
    130 #else  // GENERATED_CODE_COVERAGE
    131 
    132 #define UNSUPPORTED() printf("Unsupported instruction.\n");
    133 
    134 static void InitializeCoverage() {}
    135 
    136 
    137 void MipsDebugger::Stop(Instruction* instr) {
    138   // Get the stop code.
    139   uint32_t code = instr->Bits(25, 6);
    140   // Retrieve the encoded address, which comes just after this stop.
    141   char* msg = *reinterpret_cast<char**>(sim_->get_pc() +
    142       Instruction::kInstrSize);
    143   // Update this stop description.
    144   if (!sim_->watched_stops_[code].desc) {
    145     sim_->watched_stops_[code].desc = msg;
    146   }
    147   PrintF("Simulator hit %s (%u)\n", msg, code);
    148   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
    149   Debug();
    150 }
    151 #endif  // GENERATED_CODE_COVERAGE
    152 
    153 
    154 int32_t MipsDebugger::GetRegisterValue(int regnum) {
    155   if (regnum == kNumSimuRegisters) {
    156     return sim_->get_pc();
    157   } else {
    158     return sim_->get_register(regnum);
    159   }
    160 }
    161 
    162 
    163 int32_t MipsDebugger::GetFPURegisterValueInt(int regnum) {
    164   if (regnum == kNumFPURegisters) {
    165     return sim_->get_pc();
    166   } else {
    167     return sim_->get_fpu_register(regnum);
    168   }
    169 }
    170 
    171 
    172 int64_t MipsDebugger::GetFPURegisterValueLong(int regnum) {
    173   if (regnum == kNumFPURegisters) {
    174     return sim_->get_pc();
    175   } else {
    176     return sim_->get_fpu_register_long(regnum);
    177   }
    178 }
    179 
    180 
    181 float MipsDebugger::GetFPURegisterValueFloat(int regnum) {
    182   if (regnum == kNumFPURegisters) {
    183     return sim_->get_pc();
    184   } else {
    185     return sim_->get_fpu_register_float(regnum);
    186   }
    187 }
    188 
    189 
    190 double MipsDebugger::GetFPURegisterValueDouble(int regnum) {
    191   if (regnum == kNumFPURegisters) {
    192     return sim_->get_pc();
    193   } else {
    194     return sim_->get_fpu_register_double(regnum);
    195   }
    196 }
    197 
    198 
    199 bool MipsDebugger::GetValue(const char* desc, int32_t* value) {
    200   int regnum = Registers::Number(desc);
    201   int fpuregnum = FPURegisters::Number(desc);
    202 
    203   if (regnum != kInvalidRegister) {
    204     *value = GetRegisterValue(regnum);
    205     return true;
    206   } else if (fpuregnum != kInvalidFPURegister) {
    207     *value = GetFPURegisterValueInt(fpuregnum);
    208     return true;
    209   } else if (strncmp(desc, "0x", 2) == 0) {
    210     return SScanF(desc, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
    211   } else {
    212     return SScanF(desc, "%i", value) == 1;
    213   }
    214   return false;
    215 }
    216 
    217 
    218 bool MipsDebugger::SetBreakpoint(Instruction* breakpc) {
    219   // Check if a breakpoint can be set. If not return without any side-effects.
    220   if (sim_->break_pc_ != NULL) {
    221     return false;
    222   }
    223 
    224   // Set the breakpoint.
    225   sim_->break_pc_ = breakpc;
    226   sim_->break_instr_ = breakpc->InstructionBits();
    227   // Not setting the breakpoint instruction in the code itself. It will be set
    228   // when the debugger shell continues.
    229   return true;
    230 }
    231 
    232 
    233 bool MipsDebugger::DeleteBreakpoint(Instruction* breakpc) {
    234   if (sim_->break_pc_ != NULL) {
    235     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    236   }
    237 
    238   sim_->break_pc_ = NULL;
    239   sim_->break_instr_ = 0;
    240   return true;
    241 }
    242 
    243 
    244 void MipsDebugger::UndoBreakpoints() {
    245   if (sim_->break_pc_ != NULL) {
    246     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    247   }
    248 }
    249 
    250 
    251 void MipsDebugger::RedoBreakpoints() {
    252   if (sim_->break_pc_ != NULL) {
    253     sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
    254   }
    255 }
    256 
    257 
    258 void MipsDebugger::PrintAllRegs() {
    259 #define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)
    260 
    261   PrintF("\n");
    262   // at, v0, a0.
    263   PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    264          REG_INFO(1), REG_INFO(2), REG_INFO(4));
    265   // v1, a1.
    266   PrintF("%26s\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    267          "", REG_INFO(3), REG_INFO(5));
    268   // a2.
    269   PrintF("%26s\t%26s\t%3s: 0x%08x %10d\n", "", "", REG_INFO(6));
    270   // a3.
    271   PrintF("%26s\t%26s\t%3s: 0x%08x %10d\n", "", "", REG_INFO(7));
    272   PrintF("\n");
    273   // t0-t7, s0-s7
    274   for (int i = 0; i < 8; i++) {
    275     PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    276            REG_INFO(8+i), REG_INFO(16+i));
    277   }
    278   PrintF("\n");
    279   // t8, k0, LO.
    280   PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    281          REG_INFO(24), REG_INFO(26), REG_INFO(32));
    282   // t9, k1, HI.
    283   PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    284          REG_INFO(25), REG_INFO(27), REG_INFO(33));
    285   // sp, fp, gp.
    286   PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    287          REG_INFO(29), REG_INFO(30), REG_INFO(28));
    288   // pc.
    289   PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
    290          REG_INFO(31), REG_INFO(34));
    291 
    292 #undef REG_INFO
    293 #undef FPU_REG_INFO
    294 }
    295 
    296 
    297 void MipsDebugger::PrintAllRegsIncludingFPU() {
    298 #define FPU_REG_INFO(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \
    299         GetFPURegisterValueInt(n+1), \
    300         GetFPURegisterValueInt(n), \
    301                         GetFPURegisterValueDouble(n)
    302 
    303   PrintAllRegs();
    304 
    305   PrintF("\n\n");
    306   // f0, f1, f2, ... f31.
    307   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(0) );
    308   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(2) );
    309   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(4) );
    310   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(6) );
    311   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(8) );
    312   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(10));
    313   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(12));
    314   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(14));
    315   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(16));
    316   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(18));
    317   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(20));
    318   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(22));
    319   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(24));
    320   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(26));
    321   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(28));
    322   PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(30));
    323 
    324 #undef REG_INFO
    325 #undef FPU_REG_INFO
    326 }
    327 
    328 
    329 void MipsDebugger::Debug() {
    330   intptr_t last_pc = -1;
    331   bool done = false;
    332 
    333 #define COMMAND_SIZE 63
    334 #define ARG_SIZE 255
    335 
    336 #define STR(a) #a
    337 #define XSTR(a) STR(a)
    338 
    339   char cmd[COMMAND_SIZE + 1];
    340   char arg1[ARG_SIZE + 1];
    341   char arg2[ARG_SIZE + 1];
    342   char* argv[3] = { cmd, arg1, arg2 };
    343 
    344   // Make sure to have a proper terminating character if reaching the limit.
    345   cmd[COMMAND_SIZE] = 0;
    346   arg1[ARG_SIZE] = 0;
    347   arg2[ARG_SIZE] = 0;
    348 
    349   // Undo all set breakpoints while running in the debugger shell. This will
    350   // make them invisible to all commands.
    351   UndoBreakpoints();
    352 
    353   while (!done && (sim_->get_pc() != Simulator::end_sim_pc)) {
    354     if (last_pc != sim_->get_pc()) {
    355       disasm::NameConverter converter;
    356       disasm::Disassembler dasm(converter);
    357       // Use a reasonably large buffer.
    358       v8::internal::EmbeddedVector<char, 256> buffer;
    359       dasm.InstructionDecode(buffer,
    360                              reinterpret_cast<byte*>(sim_->get_pc()));
    361       PrintF("  0x%08x  %s\n", sim_->get_pc(), buffer.start());
    362       last_pc = sim_->get_pc();
    363     }
    364     char* line = ReadLine("sim> ");
    365     if (line == NULL) {
    366       break;
    367     } else {
    368       char* last_input = sim_->last_debugger_input();
    369       if (strcmp(line, "\n") == 0 && last_input != NULL) {
    370         line = last_input;
    371       } else {
    372         // Ownership is transferred to sim_;
    373         sim_->set_last_debugger_input(line);
    374       }
    375       // Use sscanf to parse the individual parts of the command line. At the
    376       // moment no command expects more than two parameters.
    377       int argc = SScanF(line,
    378                         "%" XSTR(COMMAND_SIZE) "s "
    379                         "%" XSTR(ARG_SIZE) "s "
    380                         "%" XSTR(ARG_SIZE) "s",
    381                         cmd, arg1, arg2);
    382       if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
    383         Instruction* instr = reinterpret_cast<Instruction*>(sim_->get_pc());
    384         if (!(instr->IsTrap()) ||
    385             instr->InstructionBits() == rtCallRedirInstr) {
    386           sim_->InstructionDecode(
    387               reinterpret_cast<Instruction*>(sim_->get_pc()));
    388         } else {
    389           // Allow si to jump over generated breakpoints.
    390           PrintF("/!\\ Jumping over generated breakpoint.\n");
    391           sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
    392         }
    393       } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
    394         // Execute the one instruction we broke at with breakpoints disabled.
    395         sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
    396         // Leave the debugger shell.
    397         done = true;
    398       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
    399         if (argc == 2) {
    400           int32_t value;
    401           float fvalue;
    402           if (strcmp(arg1, "all") == 0) {
    403             PrintAllRegs();
    404           } else if (strcmp(arg1, "allf") == 0) {
    405             PrintAllRegsIncludingFPU();
    406           } else {
    407             int regnum = Registers::Number(arg1);
    408             int fpuregnum = FPURegisters::Number(arg1);
    409 
    410             if (regnum != kInvalidRegister) {
    411               value = GetRegisterValue(regnum);
    412               PrintF("%s: 0x%08x %d \n", arg1, value, value);
    413             } else if (fpuregnum != kInvalidFPURegister) {
    414               if (fpuregnum % 2 == 1) {
    415                 value = GetFPURegisterValueInt(fpuregnum);
    416                 fvalue = GetFPURegisterValueFloat(fpuregnum);
    417                 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue);
    418               } else {
    419                 double dfvalue;
    420                 int32_t lvalue1 = GetFPURegisterValueInt(fpuregnum);
    421                 int32_t lvalue2 = GetFPURegisterValueInt(fpuregnum + 1);
    422                 dfvalue = GetFPURegisterValueDouble(fpuregnum);
    423                 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n",
    424                        FPURegisters::Name(fpuregnum+1),
    425                        FPURegisters::Name(fpuregnum),
    426                        lvalue1,
    427                        lvalue2,
    428                        dfvalue);
    429               }
    430             } else {
    431               PrintF("%s unrecognized\n", arg1);
    432             }
    433           }
    434         } else {
    435           if (argc == 3) {
    436             if (strcmp(arg2, "single") == 0) {
    437               int32_t value;
    438               float fvalue;
    439               int fpuregnum = FPURegisters::Number(arg1);
    440 
    441               if (fpuregnum != kInvalidFPURegister) {
    442                 value = GetFPURegisterValueInt(fpuregnum);
    443                 fvalue = GetFPURegisterValueFloat(fpuregnum);
    444                 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue);
    445               } else {
    446                 PrintF("%s unrecognized\n", arg1);
    447               }
    448             } else {
    449               PrintF("print <fpu register> single\n");
    450             }
    451           } else {
    452             PrintF("print <register> or print <fpu register> single\n");
    453           }
    454         }
    455       } else if ((strcmp(cmd, "po") == 0)
    456                  || (strcmp(cmd, "printobject") == 0)) {
    457         if (argc == 2) {
    458           int32_t value;
    459           if (GetValue(arg1, &value)) {
    460             Object* obj = reinterpret_cast<Object*>(value);
    461             PrintF("%s: \n", arg1);
    462 #ifdef DEBUG
    463             obj->PrintLn();
    464 #else
    465             obj->ShortPrint();
    466             PrintF("\n");
    467 #endif
    468           } else {
    469             PrintF("%s unrecognized\n", arg1);
    470           }
    471         } else {
    472           PrintF("printobject <value>\n");
    473         }
    474       } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
    475         int32_t* cur = NULL;
    476         int32_t* end = NULL;
    477         int next_arg = 1;
    478 
    479         if (strcmp(cmd, "stack") == 0) {
    480           cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp));
    481         } else {  // Command "mem".
    482           int32_t value;
    483           if (!GetValue(arg1, &value)) {
    484             PrintF("%s unrecognized\n", arg1);
    485             continue;
    486           }
    487           cur = reinterpret_cast<int32_t*>(value);
    488           next_arg++;
    489         }
    490 
    491         int32_t words;
    492         if (argc == next_arg) {
    493           words = 10;
    494         } else {
    495           if (!GetValue(argv[next_arg], &words)) {
    496             words = 10;
    497           }
    498         }
    499         end = cur + words;
    500 
    501         while (cur < end) {
    502           PrintF("  0x%08x:  0x%08x %10d",
    503                  reinterpret_cast<intptr_t>(cur), *cur, *cur);
    504           HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
    505           int value = *cur;
    506           Heap* current_heap = v8::internal::Isolate::Current()->heap();
    507           if (((value & 1) == 0) || current_heap->Contains(obj)) {
    508             PrintF(" (");
    509             if ((value & 1) == 0) {
    510               PrintF("smi %d", value / 2);
    511             } else {
    512               obj->ShortPrint();
    513             }
    514             PrintF(")");
    515           }
    516           PrintF("\n");
    517           cur++;
    518         }
    519 
    520       } else if ((strcmp(cmd, "disasm") == 0) ||
    521                  (strcmp(cmd, "dpc") == 0) ||
    522                  (strcmp(cmd, "di") == 0)) {
    523         disasm::NameConverter converter;
    524         disasm::Disassembler dasm(converter);
    525         // Use a reasonably large buffer.
    526         v8::internal::EmbeddedVector<char, 256> buffer;
    527 
    528         byte* cur = NULL;
    529         byte* end = NULL;
    530 
    531         if (argc == 1) {
    532           cur = reinterpret_cast<byte*>(sim_->get_pc());
    533           end = cur + (10 * Instruction::kInstrSize);
    534         } else if (argc == 2) {
    535           int regnum = Registers::Number(arg1);
    536           if (regnum != kInvalidRegister || strncmp(arg1, "0x", 2) == 0) {
    537             // The argument is an address or a register name.
    538             int32_t value;
    539             if (GetValue(arg1, &value)) {
    540               cur = reinterpret_cast<byte*>(value);
    541               // Disassemble 10 instructions at <arg1>.
    542               end = cur + (10 * Instruction::kInstrSize);
    543             }
    544           } else {
    545             // The argument is the number of instructions.
    546             int32_t value;
    547             if (GetValue(arg1, &value)) {
    548               cur = reinterpret_cast<byte*>(sim_->get_pc());
    549               // Disassemble <arg1> instructions.
    550               end = cur + (value * Instruction::kInstrSize);
    551             }
    552           }
    553         } else {
    554           int32_t value1;
    555           int32_t value2;
    556           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
    557             cur = reinterpret_cast<byte*>(value1);
    558             end = cur + (value2 * Instruction::kInstrSize);
    559           }
    560         }
    561 
    562         while (cur < end) {
    563           dasm.InstructionDecode(buffer, cur);
    564           PrintF("  0x%08x  %s\n",
    565               reinterpret_cast<intptr_t>(cur), buffer.start());
    566           cur += Instruction::kInstrSize;
    567         }
    568       } else if (strcmp(cmd, "gdb") == 0) {
    569         PrintF("relinquishing control to gdb\n");
    570         v8::internal::OS::DebugBreak();
    571         PrintF("regaining control from gdb\n");
    572       } else if (strcmp(cmd, "break") == 0) {
    573         if (argc == 2) {
    574           int32_t value;
    575           if (GetValue(arg1, &value)) {
    576             if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
    577               PrintF("setting breakpoint failed\n");
    578             }
    579           } else {
    580             PrintF("%s unrecognized\n", arg1);
    581           }
    582         } else {
    583           PrintF("break <address>\n");
    584         }
    585       } else if (strcmp(cmd, "del") == 0) {
    586         if (!DeleteBreakpoint(NULL)) {
    587           PrintF("deleting breakpoint failed\n");
    588         }
    589       } else if (strcmp(cmd, "flags") == 0) {
    590         PrintF("No flags on MIPS !\n");
    591       } else if (strcmp(cmd, "stop") == 0) {
    592         int32_t value;
    593         intptr_t stop_pc = sim_->get_pc() -
    594             2 * Instruction::kInstrSize;
    595         Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
    596         Instruction* msg_address =
    597           reinterpret_cast<Instruction*>(stop_pc +
    598               Instruction::kInstrSize);
    599         if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
    600           // Remove the current stop.
    601           if (sim_->IsStopInstruction(stop_instr)) {
    602             stop_instr->SetInstructionBits(kNopInstr);
    603             msg_address->SetInstructionBits(kNopInstr);
    604           } else {
    605             PrintF("Not at debugger stop.\n");
    606           }
    607         } else if (argc == 3) {
    608           // Print information about all/the specified breakpoint(s).
    609           if (strcmp(arg1, "info") == 0) {
    610             if (strcmp(arg2, "all") == 0) {
    611               PrintF("Stop information:\n");
    612               for (uint32_t i = kMaxWatchpointCode + 1;
    613                    i <= kMaxStopCode;
    614                    i++) {
    615                 sim_->PrintStopInfo(i);
    616               }
    617             } else if (GetValue(arg2, &value)) {
    618               sim_->PrintStopInfo(value);
    619             } else {
    620               PrintF("Unrecognized argument.\n");
    621             }
    622           } else if (strcmp(arg1, "enable") == 0) {
    623             // Enable all/the specified breakpoint(s).
    624             if (strcmp(arg2, "all") == 0) {
    625               for (uint32_t i = kMaxWatchpointCode + 1;
    626                    i <= kMaxStopCode;
    627                    i++) {
    628                 sim_->EnableStop(i);
    629               }
    630             } else if (GetValue(arg2, &value)) {
    631               sim_->EnableStop(value);
    632             } else {
    633               PrintF("Unrecognized argument.\n");
    634             }
    635           } else if (strcmp(arg1, "disable") == 0) {
    636             // Disable all/the specified breakpoint(s).
    637             if (strcmp(arg2, "all") == 0) {
    638               for (uint32_t i = kMaxWatchpointCode + 1;
    639                    i <= kMaxStopCode;
    640                    i++) {
    641                 sim_->DisableStop(i);
    642               }
    643             } else if (GetValue(arg2, &value)) {
    644               sim_->DisableStop(value);
    645             } else {
    646               PrintF("Unrecognized argument.\n");
    647             }
    648           }
    649         } else {
    650           PrintF("Wrong usage. Use help command for more information.\n");
    651         }
    652       } else if ((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0)) {
    653         // Print registers and disassemble.
    654         PrintAllRegs();
    655         PrintF("\n");
    656 
    657         disasm::NameConverter converter;
    658         disasm::Disassembler dasm(converter);
    659         // Use a reasonably large buffer.
    660         v8::internal::EmbeddedVector<char, 256> buffer;
    661 
    662         byte* cur = NULL;
    663         byte* end = NULL;
    664 
    665         if (argc == 1) {
    666           cur = reinterpret_cast<byte*>(sim_->get_pc());
    667           end = cur + (10 * Instruction::kInstrSize);
    668         } else if (argc == 2) {
    669           int32_t value;
    670           if (GetValue(arg1, &value)) {
    671             cur = reinterpret_cast<byte*>(value);
    672             // no length parameter passed, assume 10 instructions
    673             end = cur + (10 * Instruction::kInstrSize);
    674           }
    675         } else {
    676           int32_t value1;
    677           int32_t value2;
    678           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
    679             cur = reinterpret_cast<byte*>(value1);
    680             end = cur + (value2 * Instruction::kInstrSize);
    681           }
    682         }
    683 
    684         while (cur < end) {
    685           dasm.InstructionDecode(buffer, cur);
    686           PrintF("  0x%08x  %s\n",
    687                  reinterpret_cast<intptr_t>(cur), buffer.start());
    688           cur += Instruction::kInstrSize;
    689         }
    690       } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
    691         PrintF("cont\n");
    692         PrintF("  continue execution (alias 'c')\n");
    693         PrintF("stepi\n");
    694         PrintF("  step one instruction (alias 'si')\n");
    695         PrintF("print <register>\n");
    696         PrintF("  print register content (alias 'p')\n");
    697         PrintF("  use register name 'all' to print all registers\n");
    698         PrintF("printobject <register>\n");
    699         PrintF("  print an object from a register (alias 'po')\n");
    700         PrintF("stack [<words>]\n");
    701         PrintF("  dump stack content, default dump 10 words)\n");
    702         PrintF("mem <address> [<words>]\n");
    703         PrintF("  dump memory content, default dump 10 words)\n");
    704         PrintF("flags\n");
    705         PrintF("  print flags\n");
    706         PrintF("disasm [<instructions>]\n");
    707         PrintF("disasm [<address/register>]\n");
    708         PrintF("disasm [[<address/register>] <instructions>]\n");
    709         PrintF("  disassemble code, default is 10 instructions\n");
    710         PrintF("  from pc (alias 'di')\n");
    711         PrintF("gdb\n");
    712         PrintF("  enter gdb\n");
    713         PrintF("break <address>\n");
    714         PrintF("  set a break point on the address\n");
    715         PrintF("del\n");
    716         PrintF("  delete the breakpoint\n");
    717         PrintF("stop feature:\n");
    718         PrintF("  Description:\n");
    719         PrintF("    Stops are debug instructions inserted by\n");
    720         PrintF("    the Assembler::stop() function.\n");
    721         PrintF("    When hitting a stop, the Simulator will\n");
    722         PrintF("    stop and and give control to the Debugger.\n");
    723         PrintF("    All stop codes are watched:\n");
    724         PrintF("    - They can be enabled / disabled: the Simulator\n");
    725         PrintF("       will / won't stop when hitting them.\n");
    726         PrintF("    - The Simulator keeps track of how many times they \n");
    727         PrintF("      are met. (See the info command.) Going over a\n");
    728         PrintF("      disabled stop still increases its counter. \n");
    729         PrintF("  Commands:\n");
    730         PrintF("    stop info all/<code> : print infos about number <code>\n");
    731         PrintF("      or all stop(s).\n");
    732         PrintF("    stop enable/disable all/<code> : enables / disables\n");
    733         PrintF("      all or number <code> stop(s)\n");
    734         PrintF("    stop unstop\n");
    735         PrintF("      ignore the stop instruction at the current location\n");
    736         PrintF("      from now on\n");
    737       } else {
    738         PrintF("Unknown command: %s\n", cmd);
    739       }
    740     }
    741   }
    742 
    743   // Add all the breakpoints back to stop execution and enter the debugger
    744   // shell when hit.
    745   RedoBreakpoints();
    746 
    747 #undef COMMAND_SIZE
    748 #undef ARG_SIZE
    749 
    750 #undef STR
    751 #undef XSTR
    752 }
    753 
    754 
    755 static bool ICacheMatch(void* one, void* two) {
    756   ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
    757   ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
    758   return one == two;
    759 }
    760 
    761 
    762 static uint32_t ICacheHash(void* key) {
    763   return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
    764 }
    765 
    766 
    767 static bool AllOnOnePage(uintptr_t start, int size) {
    768   intptr_t start_page = (start & ~CachePage::kPageMask);
    769   intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
    770   return start_page == end_page;
    771 }
    772 
    773 
    774 void Simulator::set_last_debugger_input(char* input) {
    775   DeleteArray(last_debugger_input_);
    776   last_debugger_input_ = input;
    777 }
    778 
    779 
    780 void Simulator::FlushICache(v8::internal::HashMap* i_cache,
    781                             void* start_addr,
    782                             size_t size) {
    783   intptr_t start = reinterpret_cast<intptr_t>(start_addr);
    784   int intra_line = (start & CachePage::kLineMask);
    785   start -= intra_line;
    786   size += intra_line;
    787   size = ((size - 1) | CachePage::kLineMask) + 1;
    788   int offset = (start & CachePage::kPageMask);
    789   while (!AllOnOnePage(start, size - 1)) {
    790     int bytes_to_flush = CachePage::kPageSize - offset;
    791     FlushOnePage(i_cache, start, bytes_to_flush);
    792     start += bytes_to_flush;
    793     size -= bytes_to_flush;
    794     ASSERT_EQ(0, start & CachePage::kPageMask);
    795     offset = 0;
    796   }
    797   if (size != 0) {
    798     FlushOnePage(i_cache, start, size);
    799   }
    800 }
    801 
    802 
    803 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
    804   v8::internal::HashMap::Entry* entry = i_cache->Lookup(page,
    805                                                         ICacheHash(page),
    806                                                         true);
    807   if (entry->value == NULL) {
    808     CachePage* new_page = new CachePage();
    809     entry->value = new_page;
    810   }
    811   return reinterpret_cast<CachePage*>(entry->value);
    812 }
    813 
    814 
    815 // Flush from start up to and not including start + size.
    816 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache,
    817                              intptr_t start,
    818                              int size) {
    819   ASSERT(size <= CachePage::kPageSize);
    820   ASSERT(AllOnOnePage(start, size - 1));
    821   ASSERT((start & CachePage::kLineMask) == 0);
    822   ASSERT((size & CachePage::kLineMask) == 0);
    823   void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
    824   int offset = (start & CachePage::kPageMask);
    825   CachePage* cache_page = GetCachePage(i_cache, page);
    826   char* valid_bytemap = cache_page->ValidityByte(offset);
    827   memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
    828 }
    829 
    830 
    831 void Simulator::CheckICache(v8::internal::HashMap* i_cache,
    832                             Instruction* instr) {
    833   intptr_t address = reinterpret_cast<intptr_t>(instr);
    834   void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
    835   void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
    836   int offset = (address & CachePage::kPageMask);
    837   CachePage* cache_page = GetCachePage(i_cache, page);
    838   char* cache_valid_byte = cache_page->ValidityByte(offset);
    839   bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
    840   char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
    841   if (cache_hit) {
    842     // Check that the data in memory matches the contents of the I-cache.
    843     CHECK_EQ(0, memcmp(reinterpret_cast<void*>(instr),
    844                        cache_page->CachedData(offset),
    845                        Instruction::kInstrSize));
    846   } else {
    847     // Cache miss.  Load memory into the cache.
    848     memcpy(cached_line, line, CachePage::kLineLength);
    849     *cache_valid_byte = CachePage::LINE_VALID;
    850   }
    851 }
    852 
    853 
    854 void Simulator::Initialize(Isolate* isolate) {
    855   if (isolate->simulator_initialized()) return;
    856   isolate->set_simulator_initialized(true);
    857   ::v8::internal::ExternalReference::set_redirector(isolate,
    858                                                     &RedirectExternalReference);
    859 }
    860 
    861 
    862 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
    863   i_cache_ = isolate_->simulator_i_cache();
    864   if (i_cache_ == NULL) {
    865     i_cache_ = new v8::internal::HashMap(&ICacheMatch);
    866     isolate_->set_simulator_i_cache(i_cache_);
    867   }
    868   Initialize(isolate);
    869   // Set up simulator support first. Some of this information is needed to
    870   // setup the architecture state.
    871   stack_ = reinterpret_cast<char*>(malloc(stack_size_));
    872   pc_modified_ = false;
    873   icount_ = 0;
    874   break_count_ = 0;
    875   break_pc_ = NULL;
    876   break_instr_ = 0;
    877 
    878   // Set up architecture state.
    879   // All registers are initialized to zero to start with.
    880   for (int i = 0; i < kNumSimuRegisters; i++) {
    881     registers_[i] = 0;
    882   }
    883   for (int i = 0; i < kNumFPURegisters; i++) {
    884     FPUregisters_[i] = 0;
    885   }
    886   FCSR_ = 0;
    887 
    888   // The sp is initialized to point to the bottom (high address) of the
    889   // allocated stack area. To be safe in potential stack underflows we leave
    890   // some buffer below.
    891   registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64;
    892   // The ra and pc are initialized to a known bad value that will cause an
    893   // access violation if the simulator ever tries to execute it.
    894   registers_[pc] = bad_ra;
    895   registers_[ra] = bad_ra;
    896   InitializeCoverage();
    897   for (int i = 0; i < kNumExceptions; i++) {
    898     exceptions[i] = 0;
    899   }
    900 
    901   last_debugger_input_ = NULL;
    902 }
    903 
    904 
    905 Simulator::~Simulator() {
    906 }
    907 
    908 
    909 // When the generated code calls an external reference we need to catch that in
    910 // the simulator.  The external reference will be a function compiled for the
    911 // host architecture.  We need to call that function instead of trying to
    912 // execute it with the simulator.  We do that by redirecting the external
    913 // reference to a swi (software-interrupt) instruction that is handled by
    914 // the simulator.  We write the original destination of the jump just at a known
    915 // offset from the swi instruction so the simulator knows what to call.
    916 class Redirection {
    917  public:
    918   Redirection(void* external_function, ExternalReference::Type type)
    919       : external_function_(external_function),
    920         swi_instruction_(rtCallRedirInstr),
    921         type_(type),
    922         next_(NULL) {
    923     Isolate* isolate = Isolate::Current();
    924     next_ = isolate->simulator_redirection();
    925     Simulator::current(isolate)->
    926         FlushICache(isolate->simulator_i_cache(),
    927                     reinterpret_cast<void*>(&swi_instruction_),
    928                     Instruction::kInstrSize);
    929     isolate->set_simulator_redirection(this);
    930   }
    931 
    932   void* address_of_swi_instruction() {
    933     return reinterpret_cast<void*>(&swi_instruction_);
    934   }
    935 
    936   void* external_function() { return external_function_; }
    937   ExternalReference::Type type() { return type_; }
    938 
    939   static Redirection* Get(void* external_function,
    940                           ExternalReference::Type type) {
    941     Isolate* isolate = Isolate::Current();
    942     Redirection* current = isolate->simulator_redirection();
    943     for (; current != NULL; current = current->next_) {
    944       if (current->external_function_ == external_function) return current;
    945     }
    946     return new Redirection(external_function, type);
    947   }
    948 
    949   static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
    950     char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
    951     char* addr_of_redirection =
    952         addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
    953     return reinterpret_cast<Redirection*>(addr_of_redirection);
    954   }
    955 
    956   static void* ReverseRedirection(int32_t reg) {
    957     Redirection* redirection = FromSwiInstruction(
    958         reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
    959     return redirection->external_function();
    960   }
    961 
    962  private:
    963   void* external_function_;
    964   uint32_t swi_instruction_;
    965   ExternalReference::Type type_;
    966   Redirection* next_;
    967 };
    968 
    969 
    970 void* Simulator::RedirectExternalReference(void* external_function,
    971                                            ExternalReference::Type type) {
    972   Redirection* redirection = Redirection::Get(external_function, type);
    973   return redirection->address_of_swi_instruction();
    974 }
    975 
    976 
    977 // Get the active Simulator for the current thread.
    978 Simulator* Simulator::current(Isolate* isolate) {
    979   v8::internal::Isolate::PerIsolateThreadData* isolate_data =
    980        isolate->FindOrAllocatePerThreadDataForThisThread();
    981   ASSERT(isolate_data != NULL);
    982   ASSERT(isolate_data != NULL);
    983 
    984   Simulator* sim = isolate_data->simulator();
    985   if (sim == NULL) {
    986     // TODO(146): delete the simulator object when a thread/isolate goes away.
    987     sim = new Simulator(isolate);
    988     isolate_data->set_simulator(sim);
    989   }
    990   return sim;
    991 }
    992 
    993 
    994 // Sets the register in the architecture state. It will also deal with updating
    995 // Simulator internal state for special registers such as PC.
    996 void Simulator::set_register(int reg, int32_t value) {
    997   ASSERT((reg >= 0) && (reg < kNumSimuRegisters));
    998   if (reg == pc) {
    999     pc_modified_ = true;
   1000   }
   1001 
   1002   // Zero register always holds 0.
   1003   registers_[reg] = (reg == 0) ? 0 : value;
   1004 }
   1005 
   1006 
   1007 void Simulator::set_dw_register(int reg, const int* dbl) {
   1008   ASSERT((reg >= 0) && (reg < kNumSimuRegisters));
   1009   registers_[reg] = dbl[0];
   1010   registers_[reg + 1] = dbl[1];
   1011 }
   1012 
   1013 
   1014 void Simulator::set_fpu_register(int fpureg, int32_t value) {
   1015   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1016   FPUregisters_[fpureg] = value;
   1017 }
   1018 
   1019 
   1020 void Simulator::set_fpu_register_float(int fpureg, float value) {
   1021   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1022   *BitCast<float*>(&FPUregisters_[fpureg]) = value;
   1023 }
   1024 
   1025 
   1026 void Simulator::set_fpu_register_double(int fpureg, double value) {
   1027   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
   1028   *BitCast<double*>(&FPUregisters_[fpureg]) = value;
   1029 }
   1030 
   1031 
   1032 // Get the register from the architecture state. This function does handle
   1033 // the special case of accessing the PC register.
   1034 int32_t Simulator::get_register(int reg) const {
   1035   ASSERT((reg >= 0) && (reg < kNumSimuRegisters));
   1036   if (reg == 0)
   1037     return 0;
   1038   else
   1039     return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
   1040 }
   1041 
   1042 
   1043 double Simulator::get_double_from_register_pair(int reg) {
   1044   ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0));
   1045 
   1046   double dm_val = 0.0;
   1047   // Read the bits from the unsigned integer register_[] array
   1048   // into the double precision floating point value and return it.
   1049   char buffer[2 * sizeof(registers_[0])];
   1050   memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
   1051   memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
   1052   return(dm_val);
   1053 }
   1054 
   1055 
   1056 int32_t Simulator::get_fpu_register(int fpureg) const {
   1057   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1058   return FPUregisters_[fpureg];
   1059 }
   1060 
   1061 
   1062 int64_t Simulator::get_fpu_register_long(int fpureg) const {
   1063   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
   1064   return *BitCast<int64_t*>(
   1065       const_cast<int32_t*>(&FPUregisters_[fpureg]));
   1066 }
   1067 
   1068 
   1069 float Simulator::get_fpu_register_float(int fpureg) const {
   1070   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
   1071   return *BitCast<float*>(
   1072       const_cast<int32_t*>(&FPUregisters_[fpureg]));
   1073 }
   1074 
   1075 
   1076 double Simulator::get_fpu_register_double(int fpureg) const {
   1077   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
   1078   return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg]));
   1079 }
   1080 
   1081 
   1082 // Runtime FP routines take up to two double arguments and zero
   1083 // or one integer arguments. All are constructed here,
   1084 // from a0-a3 or f12 and f14.
   1085 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
   1086   if (!IsMipsSoftFloatABI) {
   1087     *x = get_fpu_register_double(12);
   1088     *y = get_fpu_register_double(14);
   1089     *z = get_register(a2);
   1090   } else {
   1091     // We use a char buffer to get around the strict-aliasing rules which
   1092     // otherwise allow the compiler to optimize away the copy.
   1093     char buffer[sizeof(*x)];
   1094     int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
   1095 
   1096     // Registers a0 and a1 -> x.
   1097     reg_buffer[0] = get_register(a0);
   1098     reg_buffer[1] = get_register(a1);
   1099     memcpy(x, buffer, sizeof(buffer));
   1100     // Registers a2 and a3 -> y.
   1101     reg_buffer[0] = get_register(a2);
   1102     reg_buffer[1] = get_register(a3);
   1103     memcpy(y, buffer, sizeof(buffer));
   1104     // Register 2 -> z.
   1105     reg_buffer[0] = get_register(a2);
   1106     memcpy(z, buffer, sizeof(*z));
   1107   }
   1108 }
   1109 
   1110 
   1111 // The return value is either in v0/v1 or f0.
   1112 void Simulator::SetFpResult(const double& result) {
   1113   if (!IsMipsSoftFloatABI) {
   1114     set_fpu_register_double(0, result);
   1115   } else {
   1116     char buffer[2 * sizeof(registers_[0])];
   1117     int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
   1118     memcpy(buffer, &result, sizeof(buffer));
   1119     // Copy result to v0 and v1.
   1120     set_register(v0, reg_buffer[0]);
   1121     set_register(v1, reg_buffer[1]);
   1122   }
   1123 }
   1124 
   1125 
   1126 // Helper functions for setting and testing the FCSR register's bits.
   1127 void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
   1128   if (value) {
   1129     FCSR_ |= (1 << cc);
   1130   } else {
   1131     FCSR_ &= ~(1 << cc);
   1132   }
   1133 }
   1134 
   1135 
   1136 bool Simulator::test_fcsr_bit(uint32_t cc) {
   1137   return FCSR_ & (1 << cc);
   1138 }
   1139 
   1140 
   1141 // Sets the rounding error codes in FCSR based on the result of the rounding.
   1142 // Returns true if the operation was invalid.
   1143 bool Simulator::set_fcsr_round_error(double original, double rounded) {
   1144   bool ret = false;
   1145 
   1146   if (!std::isfinite(original) || !std::isfinite(rounded)) {
   1147     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1148     ret = true;
   1149   }
   1150 
   1151   if (original != rounded) {
   1152     set_fcsr_bit(kFCSRInexactFlagBit, true);
   1153   }
   1154 
   1155   if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
   1156     set_fcsr_bit(kFCSRUnderflowFlagBit, true);
   1157     ret = true;
   1158   }
   1159 
   1160   if (rounded > INT_MAX || rounded < INT_MIN) {
   1161     set_fcsr_bit(kFCSROverflowFlagBit, true);
   1162     // The reference is not really clear but it seems this is required:
   1163     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
   1164     ret = true;
   1165   }
   1166 
   1167   return ret;
   1168 }
   1169 
   1170 
   1171 // Raw access to the PC register.
   1172 void Simulator::set_pc(int32_t value) {
   1173   pc_modified_ = true;
   1174   registers_[pc] = value;
   1175 }
   1176 
   1177 
   1178 bool Simulator::has_bad_pc() const {
   1179   return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc));
   1180 }
   1181 
   1182 
   1183 // Raw access to the PC register without the special adjustment when reading.
   1184 int32_t Simulator::get_pc() const {
   1185   return registers_[pc];
   1186 }
   1187 
   1188 
   1189 // The MIPS cannot do unaligned reads and writes.  On some MIPS platforms an
   1190 // interrupt is caused.  On others it does a funky rotation thing.  For now we
   1191 // simply disallow unaligned reads, but at some point we may want to move to
   1192 // emulating the rotate behaviour.  Note that simulator runs have the runtime
   1193 // system running directly on the host system and only generated code is
   1194 // executed in the simulator.  Since the host is typically IA32 we will not
   1195 // get the correct MIPS-like behaviour on unaligned accesses.
   1196 
   1197 int Simulator::ReadW(int32_t addr, Instruction* instr) {
   1198   if (addr >=0 && addr < 0x400) {
   1199     // This has to be a NULL-dereference, drop into debugger.
   1200     PrintF("Memory read from bad address: 0x%08x, pc=0x%08x\n",
   1201            addr, reinterpret_cast<intptr_t>(instr));
   1202     MipsDebugger dbg(this);
   1203     dbg.Debug();
   1204   }
   1205   if ((addr & kPointerAlignmentMask) == 0) {
   1206     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
   1207     return *ptr;
   1208   }
   1209   PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1210          addr,
   1211          reinterpret_cast<intptr_t>(instr));
   1212   MipsDebugger dbg(this);
   1213   dbg.Debug();
   1214   return 0;
   1215 }
   1216 
   1217 
   1218 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
   1219   if (addr >= 0 && addr < 0x400) {
   1220     // This has to be a NULL-dereference, drop into debugger.
   1221     PrintF("Memory write to bad address: 0x%08x, pc=0x%08x\n",
   1222            addr, reinterpret_cast<intptr_t>(instr));
   1223     MipsDebugger dbg(this);
   1224     dbg.Debug();
   1225   }
   1226   if ((addr & kPointerAlignmentMask) == 0) {
   1227     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
   1228     *ptr = value;
   1229     return;
   1230   }
   1231   PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1232          addr,
   1233          reinterpret_cast<intptr_t>(instr));
   1234   MipsDebugger dbg(this);
   1235   dbg.Debug();
   1236 }
   1237 
   1238 
   1239 double Simulator::ReadD(int32_t addr, Instruction* instr) {
   1240   if ((addr & kDoubleAlignmentMask) == 0) {
   1241     double* ptr = reinterpret_cast<double*>(addr);
   1242     return *ptr;
   1243   }
   1244   PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1245          addr,
   1246          reinterpret_cast<intptr_t>(instr));
   1247   OS::Abort();
   1248   return 0;
   1249 }
   1250 
   1251 
   1252 void Simulator::WriteD(int32_t addr, double value, Instruction* instr) {
   1253   if ((addr & kDoubleAlignmentMask) == 0) {
   1254     double* ptr = reinterpret_cast<double*>(addr);
   1255     *ptr = value;
   1256     return;
   1257   }
   1258   PrintF("Unaligned (double) write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1259          addr,
   1260          reinterpret_cast<intptr_t>(instr));
   1261   OS::Abort();
   1262 }
   1263 
   1264 
   1265 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
   1266   if ((addr & 1) == 0) {
   1267     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1268     return *ptr;
   1269   }
   1270   PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1271          addr,
   1272          reinterpret_cast<intptr_t>(instr));
   1273   OS::Abort();
   1274   return 0;
   1275 }
   1276 
   1277 
   1278 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
   1279   if ((addr & 1) == 0) {
   1280     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1281     return *ptr;
   1282   }
   1283   PrintF("Unaligned signed halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1284          addr,
   1285          reinterpret_cast<intptr_t>(instr));
   1286   OS::Abort();
   1287   return 0;
   1288 }
   1289 
   1290 
   1291 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
   1292   if ((addr & 1) == 0) {
   1293     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1294     *ptr = value;
   1295     return;
   1296   }
   1297   PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1298          addr,
   1299          reinterpret_cast<intptr_t>(instr));
   1300   OS::Abort();
   1301 }
   1302 
   1303 
   1304 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
   1305   if ((addr & 1) == 0) {
   1306     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1307     *ptr = value;
   1308     return;
   1309   }
   1310   PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1311          addr,
   1312          reinterpret_cast<intptr_t>(instr));
   1313   OS::Abort();
   1314 }
   1315 
   1316 
   1317 uint32_t Simulator::ReadBU(int32_t addr) {
   1318   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1319   return *ptr & 0xff;
   1320 }
   1321 
   1322 
   1323 int32_t Simulator::ReadB(int32_t addr) {
   1324   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1325   return *ptr;
   1326 }
   1327 
   1328 
   1329 void Simulator::WriteB(int32_t addr, uint8_t value) {
   1330   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1331   *ptr = value;
   1332 }
   1333 
   1334 
   1335 void Simulator::WriteB(int32_t addr, int8_t value) {
   1336   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1337   *ptr = value;
   1338 }
   1339 
   1340 
   1341 // Returns the limit of the stack area to enable checking for stack overflows.
   1342 uintptr_t Simulator::StackLimit() const {
   1343   // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
   1344   // pushing values.
   1345   return reinterpret_cast<uintptr_t>(stack_) + 1024;
   1346 }
   1347 
   1348 
   1349 // Unsupported instructions use Format to print an error and stop execution.
   1350 void Simulator::Format(Instruction* instr, const char* format) {
   1351   PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
   1352          reinterpret_cast<intptr_t>(instr), format);
   1353   UNIMPLEMENTED_MIPS();
   1354 }
   1355 
   1356 
   1357 // Calls into the V8 runtime are based on this very simple interface.
   1358 // Note: To be able to return two values from some calls the code in runtime.cc
   1359 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
   1360 // 64-bit value. With the code below we assume that all runtime calls return
   1361 // 64 bits of result. If they don't, the v1 result register contains a bogus
   1362 // value, which is fine because it is caller-saved.
   1363 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
   1364                                         int32_t arg1,
   1365                                         int32_t arg2,
   1366                                         int32_t arg3,
   1367                                         int32_t arg4,
   1368                                         int32_t arg5);
   1369 
   1370 // These prototypes handle the four types of FP calls.
   1371 typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
   1372 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
   1373 typedef double (*SimulatorRuntimeFPCall)(double darg0);
   1374 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
   1375 
   1376 // This signature supports direct call in to API function native callback
   1377 // (refer to InvocationCallback in v8.h).
   1378 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
   1379 typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, void* arg1);
   1380 
   1381 // This signature supports direct call to accessor getter callback.
   1382 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
   1383 typedef void (*SimulatorRuntimeProfilingGetterCall)(
   1384     int32_t arg0, int32_t arg1, void* arg2);
   1385 
   1386 // Software interrupt instructions are used by the simulator to call into the
   1387 // C-based V8 runtime. They are also used for debugging with simulator.
   1388 void Simulator::SoftwareInterrupt(Instruction* instr) {
   1389   // There are several instructions that could get us here,
   1390   // the break_ instruction, or several variants of traps. All
   1391   // Are "SPECIAL" class opcode, and are distinuished by function.
   1392   int32_t func = instr->FunctionFieldRaw();
   1393   uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;
   1394 
   1395   // We first check if we met a call_rt_redirected.
   1396   if (instr->InstructionBits() == rtCallRedirInstr) {
   1397     Redirection* redirection = Redirection::FromSwiInstruction(instr);
   1398     int32_t arg0 = get_register(a0);
   1399     int32_t arg1 = get_register(a1);
   1400     int32_t arg2 = get_register(a2);
   1401     int32_t arg3 = get_register(a3);
   1402 
   1403     int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
   1404     // Args 4 and 5 are on the stack after the reserved space for args 0..3.
   1405     int32_t arg4 = stack_pointer[4];
   1406     int32_t arg5 = stack_pointer[5];
   1407 
   1408     bool fp_call =
   1409          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
   1410          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
   1411          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
   1412          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
   1413 
   1414     if (!IsMipsSoftFloatABI) {
   1415       // With the hard floating point calling convention, double
   1416       // arguments are passed in FPU registers. Fetch the arguments
   1417       // from there and call the builtin using soft floating point
   1418       // convention.
   1419       switch (redirection->type()) {
   1420       case ExternalReference::BUILTIN_FP_FP_CALL:
   1421       case ExternalReference::BUILTIN_COMPARE_CALL:
   1422         arg0 = get_fpu_register(f12);
   1423         arg1 = get_fpu_register(f13);
   1424         arg2 = get_fpu_register(f14);
   1425         arg3 = get_fpu_register(f15);
   1426         break;
   1427       case ExternalReference::BUILTIN_FP_CALL:
   1428         arg0 = get_fpu_register(f12);
   1429         arg1 = get_fpu_register(f13);
   1430         break;
   1431       case ExternalReference::BUILTIN_FP_INT_CALL:
   1432         arg0 = get_fpu_register(f12);
   1433         arg1 = get_fpu_register(f13);
   1434         arg2 = get_register(a2);
   1435         break;
   1436       default:
   1437         break;
   1438       }
   1439     }
   1440 
   1441     // This is dodgy but it works because the C entry stubs are never moved.
   1442     // See comment in codegen-arm.cc and bug 1242173.
   1443     int32_t saved_ra = get_register(ra);
   1444 
   1445     intptr_t external =
   1446           reinterpret_cast<intptr_t>(redirection->external_function());
   1447 
   1448     // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
   1449     // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
   1450     // simulator. Soft-float has additional abstraction of ExternalReference,
   1451     // to support serialization.
   1452     if (fp_call) {
   1453       double dval0, dval1;  // one or two double parameters
   1454       int32_t ival;         // zero or one integer parameters
   1455       int64_t iresult = 0;  // integer return value
   1456       double dresult = 0;   // double return value
   1457       GetFpArgs(&dval0, &dval1, &ival);
   1458       SimulatorRuntimeCall generic_target =
   1459           reinterpret_cast<SimulatorRuntimeCall>(external);
   1460       if (::v8::internal::FLAG_trace_sim) {
   1461         switch (redirection->type()) {
   1462           case ExternalReference::BUILTIN_FP_FP_CALL:
   1463           case ExternalReference::BUILTIN_COMPARE_CALL:
   1464             PrintF("Call to host function at %p with args %f, %f",
   1465                    FUNCTION_ADDR(generic_target), dval0, dval1);
   1466             break;
   1467           case ExternalReference::BUILTIN_FP_CALL:
   1468             PrintF("Call to host function at %p with arg %f",
   1469                 FUNCTION_ADDR(generic_target), dval0);
   1470             break;
   1471           case ExternalReference::BUILTIN_FP_INT_CALL:
   1472             PrintF("Call to host function at %p with args %f, %d",
   1473                    FUNCTION_ADDR(generic_target), dval0, ival);
   1474             break;
   1475           default:
   1476             UNREACHABLE();
   1477             break;
   1478         }
   1479       }
   1480       switch (redirection->type()) {
   1481       case ExternalReference::BUILTIN_COMPARE_CALL: {
   1482         SimulatorRuntimeCompareCall target =
   1483           reinterpret_cast<SimulatorRuntimeCompareCall>(external);
   1484         iresult = target(dval0, dval1);
   1485         set_register(v0, static_cast<int32_t>(iresult));
   1486         set_register(v1, static_cast<int32_t>(iresult >> 32));
   1487         break;
   1488       }
   1489       case ExternalReference::BUILTIN_FP_FP_CALL: {
   1490         SimulatorRuntimeFPFPCall target =
   1491           reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
   1492         dresult = target(dval0, dval1);
   1493         SetFpResult(dresult);
   1494         break;
   1495       }
   1496       case ExternalReference::BUILTIN_FP_CALL: {
   1497         SimulatorRuntimeFPCall target =
   1498           reinterpret_cast<SimulatorRuntimeFPCall>(external);
   1499         dresult = target(dval0);
   1500         SetFpResult(dresult);
   1501         break;
   1502       }
   1503       case ExternalReference::BUILTIN_FP_INT_CALL: {
   1504         SimulatorRuntimeFPIntCall target =
   1505           reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
   1506         dresult = target(dval0, ival);
   1507         SetFpResult(dresult);
   1508         break;
   1509       }
   1510       default:
   1511         UNREACHABLE();
   1512         break;
   1513       }
   1514       if (::v8::internal::FLAG_trace_sim) {
   1515         switch (redirection->type()) {
   1516         case ExternalReference::BUILTIN_COMPARE_CALL:
   1517           PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
   1518           break;
   1519         case ExternalReference::BUILTIN_FP_FP_CALL:
   1520         case ExternalReference::BUILTIN_FP_CALL:
   1521         case ExternalReference::BUILTIN_FP_INT_CALL:
   1522           PrintF("Returned %f\n", dresult);
   1523           break;
   1524         default:
   1525           UNREACHABLE();
   1526           break;
   1527         }
   1528       }
   1529     } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
   1530       if (::v8::internal::FLAG_trace_sim) {
   1531         PrintF("Call to host function at %p args %08x\n",
   1532             reinterpret_cast<void*>(external), arg0);
   1533       }
   1534       SimulatorRuntimeDirectApiCall target =
   1535           reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
   1536       target(arg0);
   1537     } else if (
   1538         redirection->type() == ExternalReference::PROFILING_API_CALL) {
   1539       if (::v8::internal::FLAG_trace_sim) {
   1540         PrintF("Call to host function at %p args %08x %08x\n",
   1541             reinterpret_cast<void*>(external), arg0, arg1);
   1542       }
   1543       SimulatorRuntimeProfilingApiCall target =
   1544           reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
   1545       target(arg0, Redirection::ReverseRedirection(arg1));
   1546     } else if (
   1547         redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
   1548       if (::v8::internal::FLAG_trace_sim) {
   1549         PrintF("Call to host function at %p args %08x %08x\n",
   1550             reinterpret_cast<void*>(external), arg0, arg1);
   1551       }
   1552       SimulatorRuntimeDirectGetterCall target =
   1553           reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
   1554       target(arg0, arg1);
   1555     } else if (
   1556         redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
   1557       if (::v8::internal::FLAG_trace_sim) {
   1558         PrintF("Call to host function at %p args %08x %08x %08x\n",
   1559             reinterpret_cast<void*>(external), arg0, arg1, arg2);
   1560       }
   1561       SimulatorRuntimeProfilingGetterCall target =
   1562           reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
   1563       target(arg0, arg1, Redirection::ReverseRedirection(arg2));
   1564     } else {
   1565       SimulatorRuntimeCall target =
   1566                   reinterpret_cast<SimulatorRuntimeCall>(external);
   1567       if (::v8::internal::FLAG_trace_sim) {
   1568         PrintF(
   1569             "Call to host function at %p "
   1570             "args %08x, %08x, %08x, %08x, %08x, %08x\n",
   1571             FUNCTION_ADDR(target),
   1572             arg0,
   1573             arg1,
   1574             arg2,
   1575             arg3,
   1576             arg4,
   1577             arg5);
   1578       }
   1579       int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
   1580       set_register(v0, static_cast<int32_t>(result));
   1581       set_register(v1, static_cast<int32_t>(result >> 32));
   1582     }
   1583     if (::v8::internal::FLAG_trace_sim) {
   1584       PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0));
   1585     }
   1586     set_register(ra, saved_ra);
   1587     set_pc(get_register(ra));
   1588 
   1589   } else if (func == BREAK && code <= kMaxStopCode) {
   1590     if (IsWatchpoint(code)) {
   1591       PrintWatchpoint(code);
   1592     } else {
   1593       IncreaseStopCounter(code);
   1594       HandleStop(code, instr);
   1595     }
   1596   } else {
   1597     // All remaining break_ codes, and all traps are handled here.
   1598     MipsDebugger dbg(this);
   1599     dbg.Debug();
   1600   }
   1601 }
   1602 
   1603 
   1604 // Stop helper functions.
   1605 bool Simulator::IsWatchpoint(uint32_t code) {
   1606   return (code <= kMaxWatchpointCode);
   1607 }
   1608 
   1609 
   1610 void Simulator::PrintWatchpoint(uint32_t code) {
   1611   MipsDebugger dbg(this);
   1612   ++break_count_;
   1613   PrintF("\n---- break %d marker: %3d  (instr count: %8d) ----------"
   1614          "----------------------------------",
   1615          code, break_count_, icount_);
   1616   dbg.PrintAllRegs();  // Print registers and continue running.
   1617 }
   1618 
   1619 
   1620 void Simulator::HandleStop(uint32_t code, Instruction* instr) {
   1621   // Stop if it is enabled, otherwise go on jumping over the stop
   1622   // and the message address.
   1623   if (IsEnabledStop(code)) {
   1624     MipsDebugger dbg(this);
   1625     dbg.Stop(instr);
   1626   } else {
   1627     set_pc(get_pc() + 2 * Instruction::kInstrSize);
   1628   }
   1629 }
   1630 
   1631 
   1632 bool Simulator::IsStopInstruction(Instruction* instr) {
   1633   int32_t func = instr->FunctionFieldRaw();
   1634   uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
   1635   return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
   1636 }
   1637 
   1638 
   1639 bool Simulator::IsEnabledStop(uint32_t code) {
   1640   ASSERT(code <= kMaxStopCode);
   1641   ASSERT(code > kMaxWatchpointCode);
   1642   return !(watched_stops_[code].count & kStopDisabledBit);
   1643 }
   1644 
   1645 
   1646 void Simulator::EnableStop(uint32_t code) {
   1647   if (!IsEnabledStop(code)) {
   1648     watched_stops_[code].count &= ~kStopDisabledBit;
   1649   }
   1650 }
   1651 
   1652 
   1653 void Simulator::DisableStop(uint32_t code) {
   1654   if (IsEnabledStop(code)) {
   1655     watched_stops_[code].count |= kStopDisabledBit;
   1656   }
   1657 }
   1658 
   1659 
   1660 void Simulator::IncreaseStopCounter(uint32_t code) {
   1661   ASSERT(code <= kMaxStopCode);
   1662   if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
   1663     PrintF("Stop counter for code %i has overflowed.\n"
   1664            "Enabling this code and reseting the counter to 0.\n", code);
   1665     watched_stops_[code].count = 0;
   1666     EnableStop(code);
   1667   } else {
   1668     watched_stops_[code].count++;
   1669   }
   1670 }
   1671 
   1672 
   1673 // Print a stop status.
   1674 void Simulator::PrintStopInfo(uint32_t code) {
   1675   if (code <= kMaxWatchpointCode) {
   1676     PrintF("That is a watchpoint, not a stop.\n");
   1677     return;
   1678   } else if (code > kMaxStopCode) {
   1679     PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
   1680     return;
   1681   }
   1682   const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled";
   1683   int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
   1684   // Don't print the state of unused breakpoints.
   1685   if (count != 0) {
   1686     if (watched_stops_[code].desc) {
   1687       PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
   1688              code, code, state, count, watched_stops_[code].desc);
   1689     } else {
   1690       PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
   1691              code, code, state, count);
   1692     }
   1693   }
   1694 }
   1695 
   1696 
   1697 void Simulator::SignalExceptions() {
   1698   for (int i = 1; i < kNumExceptions; i++) {
   1699     if (exceptions[i] != 0) {
   1700       V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i);
   1701     }
   1702   }
   1703 }
   1704 
   1705 
   1706 // Handle execution based on instruction types.
   1707 
   1708 void Simulator::ConfigureTypeRegister(Instruction* instr,
   1709                                       int32_t* alu_out,
   1710                                       int64_t* i64hilo,
   1711                                       uint64_t* u64hilo,
   1712                                       int32_t* next_pc,
   1713                                       int32_t* return_addr_reg,
   1714                                       bool* do_interrupt) {
   1715   // Every local variable declared here needs to be const.
   1716   // This is to make sure that changed values are sent back to
   1717   // DecodeTypeRegister correctly.
   1718 
   1719   // Instruction fields.
   1720   const Opcode   op     = instr->OpcodeFieldRaw();
   1721   const int32_t  rs_reg = instr->RsValue();
   1722   const int32_t  rs     = get_register(rs_reg);
   1723   const uint32_t rs_u   = static_cast<uint32_t>(rs);
   1724   const int32_t  rt_reg = instr->RtValue();
   1725   const int32_t  rt     = get_register(rt_reg);
   1726   const uint32_t rt_u   = static_cast<uint32_t>(rt);
   1727   const int32_t  rd_reg = instr->RdValue();
   1728   const uint32_t sa     = instr->SaValue();
   1729 
   1730   const int32_t  fs_reg = instr->FsValue();
   1731 
   1732 
   1733   // ---------- Configuration.
   1734   switch (op) {
   1735     case COP1:    // Coprocessor instructions.
   1736       switch (instr->RsFieldRaw()) {
   1737         case BC1:   // Handled in DecodeTypeImmed, should never come here.
   1738           UNREACHABLE();
   1739           break;
   1740         case CFC1:
   1741           // At the moment only FCSR is supported.
   1742           ASSERT(fs_reg == kFCSRRegister);
   1743           *alu_out = FCSR_;
   1744           break;
   1745         case MFC1:
   1746           *alu_out = get_fpu_register(fs_reg);
   1747           break;
   1748         case MFHC1:
   1749           UNIMPLEMENTED_MIPS();
   1750           break;
   1751         case CTC1:
   1752         case MTC1:
   1753         case MTHC1:
   1754           // Do the store in the execution step.
   1755           break;
   1756         case S:
   1757         case D:
   1758         case W:
   1759         case L:
   1760         case PS:
   1761           // Do everything in the execution step.
   1762           break;
   1763         default:
   1764           UNIMPLEMENTED_MIPS();
   1765       }
   1766       break;
   1767     case COP1X:
   1768       break;
   1769     case SPECIAL:
   1770       switch (instr->FunctionFieldRaw()) {
   1771         case JR:
   1772         case JALR:
   1773           *next_pc = get_register(instr->RsValue());
   1774           *return_addr_reg = instr->RdValue();
   1775           break;
   1776         case SLL:
   1777           *alu_out = rt << sa;
   1778           break;
   1779         case SRL:
   1780           if (rs_reg == 0) {
   1781             // Regular logical right shift of a word by a fixed number of
   1782             // bits instruction. RS field is always equal to 0.
   1783             *alu_out = rt_u >> sa;
   1784           } else {
   1785             // Logical right-rotate of a word by a fixed number of bits. This
   1786             // is special case of SRL instruction, added in MIPS32 Release 2.
   1787             // RS field is equal to 00001.
   1788             *alu_out = (rt_u >> sa) | (rt_u << (32 - sa));
   1789           }
   1790           break;
   1791         case SRA:
   1792           *alu_out = rt >> sa;
   1793           break;
   1794         case SLLV:
   1795           *alu_out = rt << rs;
   1796           break;
   1797         case SRLV:
   1798           if (sa == 0) {
   1799             // Regular logical right-shift of a word by a variable number of
   1800             // bits instruction. SA field is always equal to 0.
   1801             *alu_out = rt_u >> rs;
   1802           } else {
   1803             // Logical right-rotate of a word by a variable number of bits.
   1804             // This is special case od SRLV instruction, added in MIPS32
   1805             // Release 2. SA field is equal to 00001.
   1806             *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u));
   1807           }
   1808           break;
   1809         case SRAV:
   1810           *alu_out = rt >> rs;
   1811           break;
   1812         case MFHI:
   1813           *alu_out = get_register(HI);
   1814           break;
   1815         case MFLO:
   1816           *alu_out = get_register(LO);
   1817           break;
   1818         case MULT:
   1819           *i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt);
   1820           break;
   1821         case MULTU:
   1822           *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u);
   1823           break;
   1824         case ADD:
   1825           if (HaveSameSign(rs, rt)) {
   1826             if (rs > 0) {
   1827               exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
   1828             } else if (rs < 0) {
   1829               exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
   1830             }
   1831           }
   1832           *alu_out = rs + rt;
   1833           break;
   1834         case ADDU:
   1835           *alu_out = rs + rt;
   1836           break;
   1837         case SUB:
   1838           if (!HaveSameSign(rs, rt)) {
   1839             if (rs > 0) {
   1840               exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt);
   1841             } else if (rs < 0) {
   1842               exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt);
   1843             }
   1844           }
   1845           *alu_out = rs - rt;
   1846           break;
   1847         case SUBU:
   1848           *alu_out = rs - rt;
   1849           break;
   1850         case AND:
   1851           *alu_out = rs & rt;
   1852           break;
   1853         case OR:
   1854           *alu_out = rs | rt;
   1855           break;
   1856         case XOR:
   1857           *alu_out = rs ^ rt;
   1858           break;
   1859         case NOR:
   1860           *alu_out = ~(rs | rt);
   1861           break;
   1862         case SLT:
   1863           *alu_out = rs < rt ? 1 : 0;
   1864           break;
   1865         case SLTU:
   1866           *alu_out = rs_u < rt_u ? 1 : 0;
   1867           break;
   1868         // Break and trap instructions.
   1869         case BREAK:
   1870           *do_interrupt = true;
   1871           break;
   1872         case TGE:
   1873           *do_interrupt = rs >= rt;
   1874           break;
   1875         case TGEU:
   1876           *do_interrupt = rs_u >= rt_u;
   1877           break;
   1878         case TLT:
   1879           *do_interrupt = rs < rt;
   1880           break;
   1881         case TLTU:
   1882           *do_interrupt = rs_u < rt_u;
   1883           break;
   1884         case TEQ:
   1885           *do_interrupt = rs == rt;
   1886           break;
   1887         case TNE:
   1888           *do_interrupt = rs != rt;
   1889           break;
   1890         case MOVN:
   1891         case MOVZ:
   1892         case MOVCI:
   1893           // No action taken on decode.
   1894           break;
   1895         case DIV:
   1896         case DIVU:
   1897           // div and divu never raise exceptions.
   1898           break;
   1899         default:
   1900           UNREACHABLE();
   1901       }
   1902       break;
   1903     case SPECIAL2:
   1904       switch (instr->FunctionFieldRaw()) {
   1905         case MUL:
   1906           *alu_out = rs_u * rt_u;  // Only the lower 32 bits are kept.
   1907           break;
   1908         case CLZ:
   1909           // MIPS32 spec: If no bits were set in GPR rs, the result written to
   1910           // GPR rd is 32.
   1911           // GCC __builtin_clz: If input is 0, the result is undefined.
   1912           *alu_out =
   1913               rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u);
   1914           break;
   1915         default:
   1916           UNREACHABLE();
   1917       }
   1918       break;
   1919     case SPECIAL3:
   1920       switch (instr->FunctionFieldRaw()) {
   1921         case INS: {   // Mips32r2 instruction.
   1922           // Interpret rd field as 5-bit msb of insert.
   1923           uint16_t msb = rd_reg;
   1924           // Interpret sa field as 5-bit lsb of insert.
   1925           uint16_t lsb = sa;
   1926           uint16_t size = msb - lsb + 1;
   1927           uint32_t mask = (1 << size) - 1;
   1928           *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
   1929           break;
   1930         }
   1931         case EXT: {   // Mips32r2 instruction.
   1932           // Interpret rd field as 5-bit msb of extract.
   1933           uint16_t msb = rd_reg;
   1934           // Interpret sa field as 5-bit lsb of extract.
   1935           uint16_t lsb = sa;
   1936           uint16_t size = msb + 1;
   1937           uint32_t mask = (1 << size) - 1;
   1938           *alu_out = (rs_u & (mask << lsb)) >> lsb;
   1939           break;
   1940         }
   1941         default:
   1942           UNREACHABLE();
   1943       }
   1944       break;
   1945     default:
   1946       UNREACHABLE();
   1947   }
   1948 }
   1949 
   1950 
   1951 void Simulator::DecodeTypeRegister(Instruction* instr) {
   1952   // Instruction fields.
   1953   const Opcode   op     = instr->OpcodeFieldRaw();
   1954   const int32_t  rs_reg = instr->RsValue();
   1955   const int32_t  rs     = get_register(rs_reg);
   1956   const uint32_t rs_u   = static_cast<uint32_t>(rs);
   1957   const int32_t  rt_reg = instr->RtValue();
   1958   const int32_t  rt     = get_register(rt_reg);
   1959   const uint32_t rt_u   = static_cast<uint32_t>(rt);
   1960   const int32_t  rd_reg = instr->RdValue();
   1961 
   1962   const int32_t  fr_reg = instr->FrValue();
   1963   const int32_t  fs_reg = instr->FsValue();
   1964   const int32_t  ft_reg = instr->FtValue();
   1965   const int32_t  fd_reg = instr->FdValue();
   1966   int64_t  i64hilo = 0;
   1967   uint64_t u64hilo = 0;
   1968 
   1969   // ALU output.
   1970   // It should not be used as is. Instructions using it should always
   1971   // initialize it first.
   1972   int32_t alu_out = 0x12345678;
   1973 
   1974   // For break and trap instructions.
   1975   bool do_interrupt = false;
   1976 
   1977   // For jr and jalr.
   1978   // Get current pc.
   1979   int32_t current_pc = get_pc();
   1980   // Next pc
   1981   int32_t next_pc = 0;
   1982   int32_t return_addr_reg = 31;
   1983 
   1984   // Set up the variables if needed before executing the instruction.
   1985   ConfigureTypeRegister(instr,
   1986                         &alu_out,
   1987                         &i64hilo,
   1988                         &u64hilo,
   1989                         &next_pc,
   1990                         &return_addr_reg,
   1991                         &do_interrupt);
   1992 
   1993   // ---------- Raise exceptions triggered.
   1994   SignalExceptions();
   1995 
   1996   // ---------- Execution.
   1997   switch (op) {
   1998     case COP1:
   1999       switch (instr->RsFieldRaw()) {
   2000         case BC1:   // Branch on coprocessor condition.
   2001           UNREACHABLE();
   2002           break;
   2003         case CFC1:
   2004           set_register(rt_reg, alu_out);
   2005         case MFC1:
   2006           set_register(rt_reg, alu_out);
   2007           break;
   2008         case MFHC1:
   2009           UNIMPLEMENTED_MIPS();
   2010           break;
   2011         case CTC1:
   2012           // At the moment only FCSR is supported.
   2013           ASSERT(fs_reg == kFCSRRegister);
   2014           FCSR_ = registers_[rt_reg];
   2015           break;
   2016         case MTC1:
   2017           FPUregisters_[fs_reg] = registers_[rt_reg];
   2018           break;
   2019         case MTHC1:
   2020           UNIMPLEMENTED_MIPS();
   2021           break;
   2022         case S:
   2023           float f;
   2024           switch (instr->FunctionFieldRaw()) {
   2025             case CVT_D_S:
   2026               f = get_fpu_register_float(fs_reg);
   2027               set_fpu_register_double(fd_reg, static_cast<double>(f));
   2028               break;
   2029             case CVT_W_S:
   2030             case CVT_L_S:
   2031             case TRUNC_W_S:
   2032             case TRUNC_L_S:
   2033             case ROUND_W_S:
   2034             case ROUND_L_S:
   2035             case FLOOR_W_S:
   2036             case FLOOR_L_S:
   2037             case CEIL_W_S:
   2038             case CEIL_L_S:
   2039             case CVT_PS_S:
   2040               UNIMPLEMENTED_MIPS();
   2041               break;
   2042             default:
   2043               UNREACHABLE();
   2044           }
   2045           break;
   2046         case D:
   2047           double ft, fs;
   2048           uint32_t cc, fcsr_cc;
   2049           int64_t  i64;
   2050           fs = get_fpu_register_double(fs_reg);
   2051           ft = get_fpu_register_double(ft_reg);
   2052           cc = instr->FCccValue();
   2053           fcsr_cc = get_fcsr_condition_bit(cc);
   2054           switch (instr->FunctionFieldRaw()) {
   2055             case ADD_D:
   2056               set_fpu_register_double(fd_reg, fs + ft);
   2057               break;
   2058             case SUB_D:
   2059               set_fpu_register_double(fd_reg, fs - ft);
   2060               break;
   2061             case MUL_D:
   2062               set_fpu_register_double(fd_reg, fs * ft);
   2063               break;
   2064             case DIV_D:
   2065               set_fpu_register_double(fd_reg, fs / ft);
   2066               break;
   2067             case ABS_D:
   2068               set_fpu_register_double(fd_reg, fabs(fs));
   2069               break;
   2070             case MOV_D:
   2071               set_fpu_register_double(fd_reg, fs);
   2072               break;
   2073             case NEG_D:
   2074               set_fpu_register_double(fd_reg, -fs);
   2075               break;
   2076             case SQRT_D:
   2077               set_fpu_register_double(fd_reg, sqrt(fs));
   2078               break;
   2079             case C_UN_D:
   2080               set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
   2081               break;
   2082             case C_EQ_D:
   2083               set_fcsr_bit(fcsr_cc, (fs == ft));
   2084               break;
   2085             case C_UEQ_D:
   2086               set_fcsr_bit(fcsr_cc,
   2087                            (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
   2088               break;
   2089             case C_OLT_D:
   2090               set_fcsr_bit(fcsr_cc, (fs < ft));
   2091               break;
   2092             case C_ULT_D:
   2093               set_fcsr_bit(fcsr_cc,
   2094                            (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
   2095               break;
   2096             case C_OLE_D:
   2097               set_fcsr_bit(fcsr_cc, (fs <= ft));
   2098               break;
   2099             case C_ULE_D:
   2100               set_fcsr_bit(fcsr_cc,
   2101                            (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
   2102               break;
   2103             case CVT_W_D:   // Convert double to word.
   2104               // Rounding modes are not yet supported.
   2105               ASSERT((FCSR_ & 3) == 0);
   2106               // In rounding mode 0 it should behave like ROUND.
   2107             case ROUND_W_D:  // Round double to word (round half to even).
   2108               {
   2109                 double rounded = std::floor(fs + 0.5);
   2110                 int32_t result = static_cast<int32_t>(rounded);
   2111                 if ((result & 1) != 0 && result - fs == 0.5) {
   2112                   // If the number is halfway between two integers,
   2113                   // round to the even one.
   2114                   result--;
   2115                 }
   2116                 set_fpu_register(fd_reg, result);
   2117                 if (set_fcsr_round_error(fs, rounded)) {
   2118                   set_fpu_register(fd_reg, kFPUInvalidResult);
   2119                 }
   2120               }
   2121               break;
   2122             case TRUNC_W_D:  // Truncate double to word (round towards 0).
   2123               {
   2124                 double rounded = trunc(fs);
   2125                 int32_t result = static_cast<int32_t>(rounded);
   2126                 set_fpu_register(fd_reg, result);
   2127                 if (set_fcsr_round_error(fs, rounded)) {
   2128                   set_fpu_register(fd_reg, kFPUInvalidResult);
   2129                 }
   2130               }
   2131               break;
   2132             case FLOOR_W_D:  // Round double to word towards negative infinity.
   2133               {
   2134                 double rounded = std::floor(fs);
   2135                 int32_t result = static_cast<int32_t>(rounded);
   2136                 set_fpu_register(fd_reg, result);
   2137                 if (set_fcsr_round_error(fs, rounded)) {
   2138                   set_fpu_register(fd_reg, kFPUInvalidResult);
   2139                 }
   2140               }
   2141               break;
   2142             case CEIL_W_D:  // Round double to word towards positive infinity.
   2143               {
   2144                 double rounded = std::ceil(fs);
   2145                 int32_t result = static_cast<int32_t>(rounded);
   2146                 set_fpu_register(fd_reg, result);
   2147                 if (set_fcsr_round_error(fs, rounded)) {
   2148                   set_fpu_register(fd_reg, kFPUInvalidResult);
   2149                 }
   2150               }
   2151               break;
   2152             case CVT_S_D:  // Convert double to float (single).
   2153               set_fpu_register_float(fd_reg, static_cast<float>(fs));
   2154               break;
   2155             case CVT_L_D: {  // Mips32r2: Truncate double to 64-bit long-word.
   2156               double rounded = trunc(fs);
   2157               i64 = static_cast<int64_t>(rounded);
   2158               set_fpu_register(fd_reg, i64 & 0xffffffff);
   2159               set_fpu_register(fd_reg + 1, i64 >> 32);
   2160               break;
   2161             }
   2162             case TRUNC_L_D: {  // Mips32r2 instruction.
   2163               double rounded = trunc(fs);
   2164               i64 = static_cast<int64_t>(rounded);
   2165               set_fpu_register(fd_reg, i64 & 0xffffffff);
   2166               set_fpu_register(fd_reg + 1, i64 >> 32);
   2167               break;
   2168             }
   2169             case ROUND_L_D: {  // Mips32r2 instruction.
   2170               double rounded =
   2171                   fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5);
   2172               i64 = static_cast<int64_t>(rounded);
   2173               set_fpu_register(fd_reg, i64 & 0xffffffff);
   2174               set_fpu_register(fd_reg + 1, i64 >> 32);
   2175               break;
   2176             }
   2177             case FLOOR_L_D:  // Mips32r2 instruction.
   2178               i64 = static_cast<int64_t>(std::floor(fs));
   2179               set_fpu_register(fd_reg, i64 & 0xffffffff);
   2180               set_fpu_register(fd_reg + 1, i64 >> 32);
   2181               break;
   2182             case CEIL_L_D:  // Mips32r2 instruction.
   2183               i64 = static_cast<int64_t>(std::ceil(fs));
   2184               set_fpu_register(fd_reg, i64 & 0xffffffff);
   2185               set_fpu_register(fd_reg + 1, i64 >> 32);
   2186               break;
   2187             case C_F_D:
   2188               UNIMPLEMENTED_MIPS();
   2189               break;
   2190             default:
   2191               UNREACHABLE();
   2192           }
   2193           break;
   2194         case W:
   2195           switch (instr->FunctionFieldRaw()) {
   2196             case CVT_S_W:   // Convert word to float (single).
   2197               alu_out = get_fpu_register(fs_reg);
   2198               set_fpu_register_float(fd_reg, static_cast<float>(alu_out));
   2199               break;
   2200             case CVT_D_W:   // Convert word to double.
   2201               alu_out = get_fpu_register(fs_reg);
   2202               set_fpu_register_double(fd_reg, static_cast<double>(alu_out));
   2203               break;
   2204             default:
   2205               UNREACHABLE();
   2206           }
   2207           break;
   2208         case L:
   2209           switch (instr->FunctionFieldRaw()) {
   2210           case CVT_D_L:  // Mips32r2 instruction.
   2211             // Watch the signs here, we want 2 32-bit vals
   2212             // to make a sign-64.
   2213             i64 = static_cast<uint32_t>(get_fpu_register(fs_reg));
   2214             i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32;
   2215             set_fpu_register_double(fd_reg, static_cast<double>(i64));
   2216             break;
   2217             case CVT_S_L:
   2218               UNIMPLEMENTED_MIPS();
   2219               break;
   2220             default:
   2221               UNREACHABLE();
   2222           }
   2223           break;
   2224         case PS:
   2225           break;
   2226         default:
   2227           UNREACHABLE();
   2228       }
   2229       break;
   2230     case COP1X:
   2231       switch (instr->FunctionFieldRaw()) {
   2232         case MADD_D:
   2233           double fr, ft, fs;
   2234           fr = get_fpu_register_double(fr_reg);
   2235           fs = get_fpu_register_double(fs_reg);
   2236           ft = get_fpu_register_double(ft_reg);
   2237           set_fpu_register_double(fd_reg, fs * ft + fr);
   2238           break;
   2239         default:
   2240           UNREACHABLE();
   2241       }
   2242       break;
   2243     case SPECIAL:
   2244       switch (instr->FunctionFieldRaw()) {
   2245         case JR: {
   2246           Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
   2247               current_pc+Instruction::kInstrSize);
   2248           BranchDelayInstructionDecode(branch_delay_instr);
   2249           set_pc(next_pc);
   2250           pc_modified_ = true;
   2251           break;
   2252         }
   2253         case JALR: {
   2254           Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
   2255               current_pc+Instruction::kInstrSize);
   2256           BranchDelayInstructionDecode(branch_delay_instr);
   2257           set_register(return_addr_reg,
   2258                        current_pc + 2 * Instruction::kInstrSize);
   2259           set_pc(next_pc);
   2260           pc_modified_ = true;
   2261           break;
   2262         }
   2263         // Instructions using HI and LO registers.
   2264         case MULT:
   2265           set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
   2266           set_register(HI, static_cast<int32_t>(i64hilo >> 32));
   2267           break;
   2268         case MULTU:
   2269           set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
   2270           set_register(HI, static_cast<int32_t>(u64hilo >> 32));
   2271           break;
   2272         case DIV:
   2273           // Divide by zero and overflow was not checked in the configuration
   2274           // step - div and divu do not raise exceptions. On division by 0
   2275           // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1),
   2276           // return INT_MIN which is what the hardware does.
   2277           if (rs == INT_MIN && rt == -1) {
   2278             set_register(LO, INT_MIN);
   2279             set_register(HI, 0);
   2280           } else if (rt != 0) {
   2281             set_register(LO, rs / rt);
   2282             set_register(HI, rs % rt);
   2283           }
   2284           break;
   2285         case DIVU:
   2286           if (rt_u != 0) {
   2287             set_register(LO, rs_u / rt_u);
   2288             set_register(HI, rs_u % rt_u);
   2289           }
   2290           break;
   2291         // Break and trap instructions.
   2292         case BREAK:
   2293         case TGE:
   2294         case TGEU:
   2295         case TLT:
   2296         case TLTU:
   2297         case TEQ:
   2298         case TNE:
   2299           if (do_interrupt) {
   2300             SoftwareInterrupt(instr);
   2301           }
   2302           break;
   2303         // Conditional moves.
   2304         case MOVN:
   2305           if (rt) set_register(rd_reg, rs);
   2306           break;
   2307         case MOVCI: {
   2308           uint32_t cc = instr->FBccValue();
   2309           uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
   2310           if (instr->Bit(16)) {  // Read Tf bit.
   2311             if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
   2312           } else {
   2313             if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
   2314           }
   2315           break;
   2316         }
   2317         case MOVZ:
   2318           if (!rt) set_register(rd_reg, rs);
   2319           break;
   2320         default:  // For other special opcodes we do the default operation.
   2321           set_register(rd_reg, alu_out);
   2322       }
   2323       break;
   2324     case SPECIAL2:
   2325       switch (instr->FunctionFieldRaw()) {
   2326         case MUL:
   2327           set_register(rd_reg, alu_out);
   2328           // HI and LO are UNPREDICTABLE after the operation.
   2329           set_register(LO, Unpredictable);
   2330           set_register(HI, Unpredictable);
   2331           break;
   2332         default:  // For other special2 opcodes we do the default operation.
   2333           set_register(rd_reg, alu_out);
   2334       }
   2335       break;
   2336     case SPECIAL3:
   2337       switch (instr->FunctionFieldRaw()) {
   2338         case INS:
   2339           // Ins instr leaves result in Rt, rather than Rd.
   2340           set_register(rt_reg, alu_out);
   2341           break;
   2342         case EXT:
   2343           // Ext instr leaves result in Rt, rather than Rd.
   2344           set_register(rt_reg, alu_out);
   2345           break;
   2346         default:
   2347           UNREACHABLE();
   2348       }
   2349       break;
   2350     // Unimplemented opcodes raised an error in the configuration step before,
   2351     // so we can use the default here to set the destination register in common
   2352     // cases.
   2353     default:
   2354       set_register(rd_reg, alu_out);
   2355   }
   2356 }
   2357 
   2358 
   2359 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
   2360 void Simulator::DecodeTypeImmediate(Instruction* instr) {
   2361   // Instruction fields.
   2362   Opcode   op     = instr->OpcodeFieldRaw();
   2363   int32_t  rs     = get_register(instr->RsValue());
   2364   uint32_t rs_u   = static_cast<uint32_t>(rs);
   2365   int32_t  rt_reg = instr->RtValue();  // Destination register.
   2366   int32_t  rt     = get_register(rt_reg);
   2367   int16_t  imm16  = instr->Imm16Value();
   2368 
   2369   int32_t  ft_reg = instr->FtValue();  // Destination register.
   2370 
   2371   // Zero extended immediate.
   2372   uint32_t  oe_imm16 = 0xffff & imm16;
   2373   // Sign extended immediate.
   2374   int32_t   se_imm16 = imm16;
   2375 
   2376   // Get current pc.
   2377   int32_t current_pc = get_pc();
   2378   // Next pc.
   2379   int32_t next_pc = bad_ra;
   2380 
   2381   // Used for conditional branch instructions.
   2382   bool do_branch = false;
   2383   bool execute_branch_delay_instruction = false;
   2384 
   2385   // Used for arithmetic instructions.
   2386   int32_t alu_out = 0;
   2387   // Floating point.
   2388   double fp_out = 0.0;
   2389   uint32_t cc, cc_value, fcsr_cc;
   2390 
   2391   // Used for memory instructions.
   2392   int32_t addr = 0x0;
   2393   // Value to be written in memory.
   2394   uint32_t mem_value = 0x0;
   2395 
   2396   // ---------- Configuration (and execution for REGIMM).
   2397   switch (op) {
   2398     // ------------- COP1. Coprocessor instructions.
   2399     case COP1:
   2400       switch (instr->RsFieldRaw()) {
   2401         case BC1:   // Branch on coprocessor condition.
   2402           cc = instr->FBccValue();
   2403           fcsr_cc = get_fcsr_condition_bit(cc);
   2404           cc_value = test_fcsr_bit(fcsr_cc);
   2405           do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
   2406           execute_branch_delay_instruction = true;
   2407           // Set next_pc.
   2408           if (do_branch) {
   2409             next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
   2410           } else {
   2411             next_pc = current_pc + kBranchReturnOffset;
   2412           }
   2413           break;
   2414         default:
   2415           UNREACHABLE();
   2416       }
   2417       break;
   2418     // ------------- REGIMM class.
   2419     case REGIMM:
   2420       switch (instr->RtFieldRaw()) {
   2421         case BLTZ:
   2422           do_branch = (rs  < 0);
   2423           break;
   2424         case BLTZAL:
   2425           do_branch = rs  < 0;
   2426           break;
   2427         case BGEZ:
   2428           do_branch = rs >= 0;
   2429           break;
   2430         case BGEZAL:
   2431           do_branch = rs >= 0;
   2432           break;
   2433         default:
   2434           UNREACHABLE();
   2435       }
   2436       switch (instr->RtFieldRaw()) {
   2437         case BLTZ:
   2438         case BLTZAL:
   2439         case BGEZ:
   2440         case BGEZAL:
   2441           // Branch instructions common part.
   2442           execute_branch_delay_instruction = true;
   2443           // Set next_pc.
   2444           if (do_branch) {
   2445             next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
   2446             if (instr->IsLinkingInstruction()) {
   2447               set_register(31, current_pc + kBranchReturnOffset);
   2448             }
   2449           } else {
   2450             next_pc = current_pc + kBranchReturnOffset;
   2451           }
   2452         default:
   2453           break;
   2454         }
   2455     break;  // case REGIMM.
   2456     // ------------- Branch instructions.
   2457     // When comparing to zero, the encoding of rt field is always 0, so we don't
   2458     // need to replace rt with zero.
   2459     case BEQ:
   2460       do_branch = (rs == rt);
   2461       break;
   2462     case BNE:
   2463       do_branch = rs != rt;
   2464       break;
   2465     case BLEZ:
   2466       do_branch = rs <= 0;
   2467       break;
   2468     case BGTZ:
   2469       do_branch = rs  > 0;
   2470       break;
   2471     // ------------- Arithmetic instructions.
   2472     case ADDI:
   2473       if (HaveSameSign(rs, se_imm16)) {
   2474         if (rs > 0) {
   2475           exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
   2476         } else if (rs < 0) {
   2477           exceptions[kIntegerUnderflow] =
   2478               rs < (Registers::kMinValue - se_imm16);
   2479         }
   2480       }
   2481       alu_out = rs + se_imm16;
   2482       break;
   2483     case ADDIU:
   2484       alu_out = rs + se_imm16;
   2485       break;
   2486     case SLTI:
   2487       alu_out = (rs < se_imm16) ? 1 : 0;
   2488       break;
   2489     case SLTIU:
   2490       alu_out = (rs_u < static_cast<uint32_t>(se_imm16)) ? 1 : 0;
   2491       break;
   2492     case ANDI:
   2493         alu_out = rs & oe_imm16;
   2494       break;
   2495     case ORI:
   2496         alu_out = rs | oe_imm16;
   2497       break;
   2498     case XORI:
   2499         alu_out = rs ^ oe_imm16;
   2500       break;
   2501     case LUI:
   2502         alu_out = (oe_imm16 << 16);
   2503       break;
   2504     // ------------- Memory instructions.
   2505     case LB:
   2506       addr = rs + se_imm16;
   2507       alu_out = ReadB(addr);
   2508       break;
   2509     case LH:
   2510       addr = rs + se_imm16;
   2511       alu_out = ReadH(addr, instr);
   2512       break;
   2513     case LWL: {
   2514       // al_offset is offset of the effective address within an aligned word.
   2515       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
   2516       uint8_t byte_shift = kPointerAlignmentMask - al_offset;
   2517       uint32_t mask = (1 << byte_shift * 8) - 1;
   2518       addr = rs + se_imm16 - al_offset;
   2519       alu_out = ReadW(addr, instr);
   2520       alu_out <<= byte_shift * 8;
   2521       alu_out |= rt & mask;
   2522       break;
   2523     }
   2524     case LW:
   2525       addr = rs + se_imm16;
   2526       alu_out = ReadW(addr, instr);
   2527       break;
   2528     case LBU:
   2529       addr = rs + se_imm16;
   2530       alu_out = ReadBU(addr);
   2531       break;
   2532     case LHU:
   2533       addr = rs + se_imm16;
   2534       alu_out = ReadHU(addr, instr);
   2535       break;
   2536     case LWR: {
   2537       // al_offset is offset of the effective address within an aligned word.
   2538       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
   2539       uint8_t byte_shift = kPointerAlignmentMask - al_offset;
   2540       uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
   2541       addr = rs + se_imm16 - al_offset;
   2542       alu_out = ReadW(addr, instr);
   2543       alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
   2544       alu_out |= rt & mask;
   2545       break;
   2546     }
   2547     case SB:
   2548       addr = rs + se_imm16;
   2549       break;
   2550     case SH:
   2551       addr = rs + se_imm16;
   2552       break;
   2553     case SWL: {
   2554       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
   2555       uint8_t byte_shift = kPointerAlignmentMask - al_offset;
   2556       uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
   2557       addr = rs + se_imm16 - al_offset;
   2558       mem_value = ReadW(addr, instr) & mask;
   2559       mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
   2560       break;
   2561     }
   2562     case SW:
   2563       addr = rs + se_imm16;
   2564       break;
   2565     case SWR: {
   2566       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
   2567       uint32_t mask = (1 << al_offset * 8) - 1;
   2568       addr = rs + se_imm16 - al_offset;
   2569       mem_value = ReadW(addr, instr);
   2570       mem_value = (rt << al_offset * 8) | (mem_value & mask);
   2571       break;
   2572     }
   2573     case LWC1:
   2574       addr = rs + se_imm16;
   2575       alu_out = ReadW(addr, instr);
   2576       break;
   2577     case LDC1:
   2578       addr = rs + se_imm16;
   2579       fp_out = ReadD(addr, instr);
   2580       break;
   2581     case SWC1:
   2582     case SDC1:
   2583       addr = rs + se_imm16;
   2584       break;
   2585     default:
   2586       UNREACHABLE();
   2587   }
   2588 
   2589   // ---------- Raise exceptions triggered.
   2590   SignalExceptions();
   2591 
   2592   // ---------- Execution.
   2593   switch (op) {
   2594     // ------------- Branch instructions.
   2595     case BEQ:
   2596     case BNE:
   2597     case BLEZ:
   2598     case BGTZ:
   2599       // Branch instructions common part.
   2600       execute_branch_delay_instruction = true;
   2601       // Set next_pc.
   2602       if (do_branch) {
   2603         next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
   2604         if (instr->IsLinkingInstruction()) {
   2605           set_register(31, current_pc + 2* Instruction::kInstrSize);
   2606         }
   2607       } else {
   2608         next_pc = current_pc + 2 * Instruction::kInstrSize;
   2609       }
   2610       break;
   2611     // ------------- Arithmetic instructions.
   2612     case ADDI:
   2613     case ADDIU:
   2614     case SLTI:
   2615     case SLTIU:
   2616     case ANDI:
   2617     case ORI:
   2618     case XORI:
   2619     case LUI:
   2620       set_register(rt_reg, alu_out);
   2621       break;
   2622     // ------------- Memory instructions.
   2623     case LB:
   2624     case LH:
   2625     case LWL:
   2626     case LW:
   2627     case LBU:
   2628     case LHU:
   2629     case LWR:
   2630       set_register(rt_reg, alu_out);
   2631       break;
   2632     case SB:
   2633       WriteB(addr, static_cast<int8_t>(rt));
   2634       break;
   2635     case SH:
   2636       WriteH(addr, static_cast<uint16_t>(rt), instr);
   2637       break;
   2638     case SWL:
   2639       WriteW(addr, mem_value, instr);
   2640       break;
   2641     case SW:
   2642       WriteW(addr, rt, instr);
   2643       break;
   2644     case SWR:
   2645       WriteW(addr, mem_value, instr);
   2646       break;
   2647     case LWC1:
   2648       set_fpu_register(ft_reg, alu_out);
   2649       break;
   2650     case LDC1:
   2651       set_fpu_register_double(ft_reg, fp_out);
   2652       break;
   2653     case SWC1:
   2654       addr = rs + se_imm16;
   2655       WriteW(addr, get_fpu_register(ft_reg), instr);
   2656       break;
   2657     case SDC1:
   2658       addr = rs + se_imm16;
   2659       WriteD(addr, get_fpu_register_double(ft_reg), instr);
   2660       break;
   2661     default:
   2662       break;
   2663   }
   2664 
   2665 
   2666   if (execute_branch_delay_instruction) {
   2667     // Execute branch delay slot
   2668     // We don't check for end_sim_pc. First it should not be met as the current
   2669     // pc is valid. Secondly a jump should always execute its branch delay slot.
   2670     Instruction* branch_delay_instr =
   2671       reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize);
   2672     BranchDelayInstructionDecode(branch_delay_instr);
   2673   }
   2674 
   2675   // If needed update pc after the branch delay execution.
   2676   if (next_pc != bad_ra) {
   2677     set_pc(next_pc);
   2678   }
   2679 }
   2680 
   2681 
   2682 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
   2683 void Simulator::DecodeTypeJump(Instruction* instr) {
   2684   // Get current pc.
   2685   int32_t current_pc = get_pc();
   2686   // Get unchanged bits of pc.
   2687   int32_t pc_high_bits = current_pc & 0xf0000000;
   2688   // Next pc.
   2689   int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);
   2690 
   2691   // Execute branch delay slot.
   2692   // We don't check for end_sim_pc. First it should not be met as the current pc
   2693   // is valid. Secondly a jump should always execute its branch delay slot.
   2694   Instruction* branch_delay_instr =
   2695       reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
   2696   BranchDelayInstructionDecode(branch_delay_instr);
   2697 
   2698   // Update pc and ra if necessary.
   2699   // Do this after the branch delay execution.
   2700   if (instr->IsLinkingInstruction()) {
   2701     set_register(31, current_pc + 2 * Instruction::kInstrSize);
   2702   }
   2703   set_pc(next_pc);
   2704   pc_modified_ = true;
   2705 }
   2706 
   2707 
   2708 // Executes the current instruction.
   2709 void Simulator::InstructionDecode(Instruction* instr) {
   2710   if (v8::internal::FLAG_check_icache) {
   2711     CheckICache(isolate_->simulator_i_cache(), instr);
   2712   }
   2713   pc_modified_ = false;
   2714   if (::v8::internal::FLAG_trace_sim) {
   2715     disasm::NameConverter converter;
   2716     disasm::Disassembler dasm(converter);
   2717     // Use a reasonably large buffer.
   2718     v8::internal::EmbeddedVector<char, 256> buffer;
   2719     dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
   2720     PrintF("  0x%08x  %s\n", reinterpret_cast<intptr_t>(instr),
   2721         buffer.start());
   2722   }
   2723 
   2724   switch (instr->InstructionType()) {
   2725     case Instruction::kRegisterType:
   2726       DecodeTypeRegister(instr);
   2727       break;
   2728     case Instruction::kImmediateType:
   2729       DecodeTypeImmediate(instr);
   2730       break;
   2731     case Instruction::kJumpType:
   2732       DecodeTypeJump(instr);
   2733       break;
   2734     default:
   2735       UNSUPPORTED();
   2736   }
   2737   if (!pc_modified_) {
   2738     set_register(pc, reinterpret_cast<int32_t>(instr) +
   2739                  Instruction::kInstrSize);
   2740   }
   2741 }
   2742 
   2743 
   2744 
   2745 void Simulator::Execute() {
   2746   // Get the PC to simulate. Cannot use the accessor here as we need the
   2747   // raw PC value and not the one used as input to arithmetic instructions.
   2748   int program_counter = get_pc();
   2749   if (::v8::internal::FLAG_stop_sim_at == 0) {
   2750     // Fast version of the dispatch loop without checking whether the simulator
   2751     // should be stopping at a particular executed instruction.
   2752     while (program_counter != end_sim_pc) {
   2753       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
   2754       icount_++;
   2755       InstructionDecode(instr);
   2756       program_counter = get_pc();
   2757     }
   2758   } else {
   2759     // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
   2760     // we reach the particular instuction count.
   2761     while (program_counter != end_sim_pc) {
   2762       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
   2763       icount_++;
   2764       if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
   2765         MipsDebugger dbg(this);
   2766         dbg.Debug();
   2767       } else {
   2768         InstructionDecode(instr);
   2769       }
   2770       program_counter = get_pc();
   2771     }
   2772   }
   2773 }
   2774 
   2775 
   2776 void Simulator::CallInternal(byte* entry) {
   2777   // Prepare to execute the code at entry.
   2778   set_register(pc, reinterpret_cast<int32_t>(entry));
   2779   // Put down marker for end of simulation. The simulator will stop simulation
   2780   // when the PC reaches this value. By saving the "end simulation" value into
   2781   // the LR the simulation stops when returning to this call point.
   2782   set_register(ra, end_sim_pc);
   2783 
   2784   // Remember the values of callee-saved registers.
   2785   // The code below assumes that r9 is not used as sb (static base) in
   2786   // simulator code and therefore is regarded as a callee-saved register.
   2787   int32_t s0_val = get_register(s0);
   2788   int32_t s1_val = get_register(s1);
   2789   int32_t s2_val = get_register(s2);
   2790   int32_t s3_val = get_register(s3);
   2791   int32_t s4_val = get_register(s4);
   2792   int32_t s5_val = get_register(s5);
   2793   int32_t s6_val = get_register(s6);
   2794   int32_t s7_val = get_register(s7);
   2795   int32_t gp_val = get_register(gp);
   2796   int32_t sp_val = get_register(sp);
   2797   int32_t fp_val = get_register(fp);
   2798 
   2799   // Set up the callee-saved registers with a known value. To be able to check
   2800   // that they are preserved properly across JS execution.
   2801   int32_t callee_saved_value = icount_;
   2802   set_register(s0, callee_saved_value);
   2803   set_register(s1, callee_saved_value);
   2804   set_register(s2, callee_saved_value);
   2805   set_register(s3, callee_saved_value);
   2806   set_register(s4, callee_saved_value);
   2807   set_register(s5, callee_saved_value);
   2808   set_register(s6, callee_saved_value);
   2809   set_register(s7, callee_saved_value);
   2810   set_register(gp, callee_saved_value);
   2811   set_register(fp, callee_saved_value);
   2812 
   2813   // Start the simulation.
   2814   Execute();
   2815 
   2816   // Check that the callee-saved registers have been preserved.
   2817   CHECK_EQ(callee_saved_value, get_register(s0));
   2818   CHECK_EQ(callee_saved_value, get_register(s1));
   2819   CHECK_EQ(callee_saved_value, get_register(s2));
   2820   CHECK_EQ(callee_saved_value, get_register(s3));
   2821   CHECK_EQ(callee_saved_value, get_register(s4));
   2822   CHECK_EQ(callee_saved_value, get_register(s5));
   2823   CHECK_EQ(callee_saved_value, get_register(s6));
   2824   CHECK_EQ(callee_saved_value, get_register(s7));
   2825   CHECK_EQ(callee_saved_value, get_register(gp));
   2826   CHECK_EQ(callee_saved_value, get_register(fp));
   2827 
   2828   // Restore callee-saved registers with the original value.
   2829   set_register(s0, s0_val);
   2830   set_register(s1, s1_val);
   2831   set_register(s2, s2_val);
   2832   set_register(s3, s3_val);
   2833   set_register(s4, s4_val);
   2834   set_register(s5, s5_val);
   2835   set_register(s6, s6_val);
   2836   set_register(s7, s7_val);
   2837   set_register(gp, gp_val);
   2838   set_register(sp, sp_val);
   2839   set_register(fp, fp_val);
   2840 }
   2841 
   2842 
   2843 int32_t Simulator::Call(byte* entry, int argument_count, ...) {
   2844   va_list parameters;
   2845   va_start(parameters, argument_count);
   2846   // Set up arguments.
   2847 
   2848   // First four arguments passed in registers.
   2849   ASSERT(argument_count >= 4);
   2850   set_register(a0, va_arg(parameters, int32_t));
   2851   set_register(a1, va_arg(parameters, int32_t));
   2852   set_register(a2, va_arg(parameters, int32_t));
   2853   set_register(a3, va_arg(parameters, int32_t));
   2854 
   2855   // Remaining arguments passed on stack.
   2856   int original_stack = get_register(sp);
   2857   // Compute position of stack on entry to generated code.
   2858   int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t)
   2859                                     - kCArgsSlotsSize);
   2860   if (OS::ActivationFrameAlignment() != 0) {
   2861     entry_stack &= -OS::ActivationFrameAlignment();
   2862   }
   2863   // Store remaining arguments on stack, from low to high memory.
   2864   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
   2865   for (int i = 4; i < argument_count; i++) {
   2866     stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t);
   2867   }
   2868   va_end(parameters);
   2869   set_register(sp, entry_stack);
   2870 
   2871   CallInternal(entry);
   2872 
   2873   // Pop stack passed arguments.
   2874   CHECK_EQ(entry_stack, get_register(sp));
   2875   set_register(sp, original_stack);
   2876 
   2877   int32_t result = get_register(v0);
   2878   return result;
   2879 }
   2880 
   2881 
   2882 double Simulator::CallFP(byte* entry, double d0, double d1) {
   2883   if (!IsMipsSoftFloatABI) {
   2884     set_fpu_register_double(f12, d0);
   2885     set_fpu_register_double(f14, d1);
   2886   } else {
   2887     int buffer[2];
   2888     ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0));
   2889     memcpy(buffer, &d0, sizeof(d0));
   2890     set_dw_register(a0, buffer);
   2891     memcpy(buffer, &d1, sizeof(d1));
   2892     set_dw_register(a2, buffer);
   2893   }
   2894   CallInternal(entry);
   2895   if (!IsMipsSoftFloatABI) {
   2896     return get_fpu_register_double(f0);
   2897   } else {
   2898     return get_double_from_register_pair(v0);
   2899   }
   2900 }
   2901 
   2902 
   2903 uintptr_t Simulator::PushAddress(uintptr_t address) {
   2904   int new_sp = get_register(sp) - sizeof(uintptr_t);
   2905   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
   2906   *stack_slot = address;
   2907   set_register(sp, new_sp);
   2908   return new_sp;
   2909 }
   2910 
   2911 
   2912 uintptr_t Simulator::PopAddress() {
   2913   int current_sp = get_register(sp);
   2914   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
   2915   uintptr_t address = *stack_slot;
   2916   set_register(sp, current_sp + sizeof(uintptr_t));
   2917   return address;
   2918 }
   2919 
   2920 
   2921 #undef UNSUPPORTED
   2922 
   2923 } }  // namespace v8::internal
   2924 
   2925 #endif  // USE_SIMULATOR
   2926 
   2927 #endif  // V8_TARGET_ARCH_MIPS
   2928