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