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