b7e53c9faa99dd1e86d2b43527a521d4b2b4a7f6
[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  private:
976   void* external_function_;
977   uint32_t swi_instruction_;
978   ExternalReference::Type type_;
979   Redirection* next_;
980 };
981
982
983 void* Simulator::RedirectExternalReference(void* external_function,
984                                            ExternalReference::Type type) {
985   Redirection* redirection = Redirection::Get(external_function, type);
986   return redirection->address_of_swi_instruction();
987 }
988
989
990 // Get the active Simulator for the current thread.
991 Simulator* Simulator::current(Isolate* isolate) {
992   v8::internal::Isolate::PerIsolateThreadData* isolate_data =
993        isolate->FindOrAllocatePerThreadDataForThisThread();
994   ASSERT(isolate_data != NULL);
995   ASSERT(isolate_data != NULL);
996
997   Simulator* sim = isolate_data->simulator();
998   if (sim == NULL) {
999     // TODO(146): delete the simulator object when a thread/isolate goes away.
1000     sim = new Simulator(isolate);
1001     isolate_data->set_simulator(sim);
1002   }
1003   return sim;
1004 }
1005
1006
1007 // Sets the register in the architecture state. It will also deal with updating
1008 // Simulator internal state for special registers such as PC.
1009 void Simulator::set_register(int reg, int32_t value) {
1010   ASSERT((reg >= 0) && (reg < kNumSimuRegisters));
1011   if (reg == pc) {
1012     pc_modified_ = true;
1013   }
1014
1015   // Zero register always holds 0.
1016   registers_[reg] = (reg == 0) ? 0 : value;
1017 }
1018
1019
1020 void Simulator::set_dw_register(int reg, const int* dbl) {
1021   ASSERT((reg >= 0) && (reg < kNumSimuRegisters));
1022   registers_[reg] = dbl[0];
1023   registers_[reg + 1] = dbl[1];
1024 }
1025
1026
1027 void Simulator::set_fpu_register(int fpureg, int32_t value) {
1028   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
1029   FPUregisters_[fpureg] = value;
1030 }
1031
1032
1033 void Simulator::set_fpu_register_float(int fpureg, float value) {
1034   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
1035   *BitCast<float*>(&FPUregisters_[fpureg]) = value;
1036 }
1037
1038
1039 void Simulator::set_fpu_register_double(int fpureg, double value) {
1040   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
1041   *BitCast<double*>(&FPUregisters_[fpureg]) = value;
1042 }
1043
1044
1045 // Get the register from the architecture state. This function does handle
1046 // the special case of accessing the PC register.
1047 int32_t Simulator::get_register(int reg) const {
1048   ASSERT((reg >= 0) && (reg < kNumSimuRegisters));
1049   if (reg == 0)
1050     return 0;
1051   else
1052     return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
1053 }
1054
1055
1056 double Simulator::get_double_from_register_pair(int reg) {
1057   ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0));
1058
1059   double dm_val = 0.0;
1060   // Read the bits from the unsigned integer register_[] array
1061   // into the double precision floating point value and return it.
1062   char buffer[2 * sizeof(registers_[0])];
1063   OS::MemCopy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
1064   OS::MemCopy(&dm_val, buffer, 2 * sizeof(registers_[0]));
1065   return(dm_val);
1066 }
1067
1068
1069 int32_t Simulator::get_fpu_register(int fpureg) const {
1070   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
1071   return FPUregisters_[fpureg];
1072 }
1073
1074
1075 int64_t Simulator::get_fpu_register_long(int fpureg) const {
1076   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
1077   return *BitCast<int64_t*>(
1078       const_cast<int32_t*>(&FPUregisters_[fpureg]));
1079 }
1080
1081
1082 float Simulator::get_fpu_register_float(int fpureg) const {
1083   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
1084   return *BitCast<float*>(
1085       const_cast<int32_t*>(&FPUregisters_[fpureg]));
1086 }
1087
1088
1089 double Simulator::get_fpu_register_double(int fpureg) const {
1090   ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
1091   return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg]));
1092 }
1093
1094
1095 // Runtime FP routines take up to two double arguments and zero
1096 // or one integer arguments. All are constructed here,
1097 // from a0-a3 or f12 and f14.
1098 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
1099   if (!IsMipsSoftFloatABI) {
1100     *x = get_fpu_register_double(12);
1101     *y = get_fpu_register_double(14);
1102     *z = get_register(a2);
1103   } else {
1104     // We use a char buffer to get around the strict-aliasing rules which
1105     // otherwise allow the compiler to optimize away the copy.
1106     char buffer[sizeof(*x)];
1107     int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1108
1109     // Registers a0 and a1 -> x.
1110     reg_buffer[0] = get_register(a0);
1111     reg_buffer[1] = get_register(a1);
1112     OS::MemCopy(x, buffer, sizeof(buffer));
1113     // Registers a2 and a3 -> y.
1114     reg_buffer[0] = get_register(a2);
1115     reg_buffer[1] = get_register(a3);
1116     OS::MemCopy(y, buffer, sizeof(buffer));
1117     // Register 2 -> z.
1118     reg_buffer[0] = get_register(a2);
1119     OS::MemCopy(z, buffer, sizeof(*z));
1120   }
1121 }
1122
1123
1124 // The return value is either in v0/v1 or f0.
1125 void Simulator::SetFpResult(const double& result) {
1126   if (!IsMipsSoftFloatABI) {
1127     set_fpu_register_double(0, result);
1128   } else {
1129     char buffer[2 * sizeof(registers_[0])];
1130     int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1131     OS::MemCopy(buffer, &result, sizeof(buffer));
1132     // Copy result to v0 and v1.
1133     set_register(v0, reg_buffer[0]);
1134     set_register(v1, reg_buffer[1]);
1135   }
1136 }
1137
1138
1139 // Helper functions for setting and testing the FCSR register's bits.
1140 void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
1141   if (value) {
1142     FCSR_ |= (1 << cc);
1143   } else {
1144     FCSR_ &= ~(1 << cc);
1145   }
1146 }
1147
1148
1149 bool Simulator::test_fcsr_bit(uint32_t cc) {
1150   return FCSR_ & (1 << cc);
1151 }
1152
1153
1154 // Sets the rounding error codes in FCSR based on the result of the rounding.
1155 // Returns true if the operation was invalid.
1156 bool Simulator::set_fcsr_round_error(double original, double rounded) {
1157   bool ret = false;
1158
1159   if (!std::isfinite(original) || !std::isfinite(rounded)) {
1160     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1161     ret = true;
1162   }
1163
1164   if (original != rounded) {
1165     set_fcsr_bit(kFCSRInexactFlagBit, true);
1166   }
1167
1168   if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
1169     set_fcsr_bit(kFCSRUnderflowFlagBit, true);
1170     ret = true;
1171   }
1172
1173   if (rounded > INT_MAX || rounded < INT_MIN) {
1174     set_fcsr_bit(kFCSROverflowFlagBit, true);
1175     // The reference is not really clear but it seems this is required:
1176     set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1177     ret = true;
1178   }
1179
1180   return ret;
1181 }
1182
1183
1184 // Raw access to the PC register.
1185 void Simulator::set_pc(int32_t value) {
1186   pc_modified_ = true;
1187   registers_[pc] = value;
1188 }
1189
1190
1191 bool Simulator::has_bad_pc() const {
1192   return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc));
1193 }
1194
1195
1196 // Raw access to the PC register without the special adjustment when reading.
1197 int32_t Simulator::get_pc() const {
1198   return registers_[pc];
1199 }
1200
1201
1202 // The MIPS cannot do unaligned reads and writes.  On some MIPS platforms an
1203 // interrupt is caused.  On others it does a funky rotation thing.  For now we
1204 // simply disallow unaligned reads, but at some point we may want to move to
1205 // emulating the rotate behaviour.  Note that simulator runs have the runtime
1206 // system running directly on the host system and only generated code is
1207 // executed in the simulator.  Since the host is typically IA32 we will not
1208 // get the correct MIPS-like behaviour on unaligned accesses.
1209
1210 int Simulator::ReadW(int32_t addr, Instruction* instr) {
1211   if (addr >=0 && addr < 0x400) {
1212     // This has to be a NULL-dereference, drop into debugger.
1213     PrintF("Memory read from bad address: 0x%08x, pc=0x%08x\n",
1214            addr, reinterpret_cast<intptr_t>(instr));
1215     MipsDebugger dbg(this);
1216     dbg.Debug();
1217   }
1218   if ((addr & kPointerAlignmentMask) == 0) {
1219     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1220     return *ptr;
1221   }
1222   PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1223          addr,
1224          reinterpret_cast<intptr_t>(instr));
1225   MipsDebugger dbg(this);
1226   dbg.Debug();
1227   return 0;
1228 }
1229
1230
1231 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
1232   if (addr >= 0 && addr < 0x400) {
1233     // This has to be a NULL-dereference, drop into debugger.
1234     PrintF("Memory write to bad address: 0x%08x, pc=0x%08x\n",
1235            addr, reinterpret_cast<intptr_t>(instr));
1236     MipsDebugger dbg(this);
1237     dbg.Debug();
1238   }
1239   if ((addr & kPointerAlignmentMask) == 0) {
1240     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1241     *ptr = value;
1242     return;
1243   }
1244   PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1245          addr,
1246          reinterpret_cast<intptr_t>(instr));
1247   MipsDebugger dbg(this);
1248   dbg.Debug();
1249 }
1250
1251
1252 double Simulator::ReadD(int32_t addr, Instruction* instr) {
1253   if ((addr & kDoubleAlignmentMask) == 0) {
1254     double* ptr = reinterpret_cast<double*>(addr);
1255     return *ptr;
1256   }
1257   PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1258          addr,
1259          reinterpret_cast<intptr_t>(instr));
1260   OS::Abort();
1261   return 0;
1262 }
1263
1264
1265 void Simulator::WriteD(int32_t addr, double value, Instruction* instr) {
1266   if ((addr & kDoubleAlignmentMask) == 0) {
1267     double* ptr = reinterpret_cast<double*>(addr);
1268     *ptr = value;
1269     return;
1270   }
1271   PrintF("Unaligned (double) write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1272          addr,
1273          reinterpret_cast<intptr_t>(instr));
1274   OS::Abort();
1275 }
1276
1277
1278 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
1279   if ((addr & 1) == 0) {
1280     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1281     return *ptr;
1282   }
1283   PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1284          addr,
1285          reinterpret_cast<intptr_t>(instr));
1286   OS::Abort();
1287   return 0;
1288 }
1289
1290
1291 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
1292   if ((addr & 1) == 0) {
1293     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1294     return *ptr;
1295   }
1296   PrintF("Unaligned signed halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1297          addr,
1298          reinterpret_cast<intptr_t>(instr));
1299   OS::Abort();
1300   return 0;
1301 }
1302
1303
1304 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
1305   if ((addr & 1) == 0) {
1306     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1307     *ptr = value;
1308     return;
1309   }
1310   PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1311          addr,
1312          reinterpret_cast<intptr_t>(instr));
1313   OS::Abort();
1314 }
1315
1316
1317 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
1318   if ((addr & 1) == 0) {
1319     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1320     *ptr = value;
1321     return;
1322   }
1323   PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1324          addr,
1325          reinterpret_cast<intptr_t>(instr));
1326   OS::Abort();
1327 }
1328
1329
1330 uint32_t Simulator::ReadBU(int32_t addr) {
1331   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1332   return *ptr & 0xff;
1333 }
1334
1335
1336 int32_t Simulator::ReadB(int32_t addr) {
1337   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1338   return *ptr;
1339 }
1340
1341
1342 void Simulator::WriteB(int32_t addr, uint8_t value) {
1343   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1344   *ptr = value;
1345 }
1346
1347
1348 void Simulator::WriteB(int32_t addr, int8_t value) {
1349   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1350   *ptr = value;
1351 }
1352
1353
1354 // Returns the limit of the stack area to enable checking for stack overflows.
1355 uintptr_t Simulator::StackLimit() const {
1356   // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
1357   // pushing values.
1358   return reinterpret_cast<uintptr_t>(stack_) + 1024;
1359 }
1360
1361
1362 // Unsupported instructions use Format to print an error and stop execution.
1363 void Simulator::Format(Instruction* instr, const char* format) {
1364   PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
1365          reinterpret_cast<intptr_t>(instr), format);
1366   UNIMPLEMENTED_MIPS();
1367 }
1368
1369
1370 // Calls into the V8 runtime are based on this very simple interface.
1371 // Note: To be able to return two values from some calls the code in runtime.cc
1372 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
1373 // 64-bit value. With the code below we assume that all runtime calls return
1374 // 64 bits of result. If they don't, the v1 result register contains a bogus
1375 // value, which is fine because it is caller-saved.
1376 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1377                                         int32_t arg1,
1378                                         int32_t arg2,
1379                                         int32_t arg3,
1380                                         int32_t arg4,
1381                                         int32_t arg5);
1382
1383 // These prototypes handle the four types of FP calls.
1384 typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
1385 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
1386 typedef double (*SimulatorRuntimeFPCall)(double darg0);
1387 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
1388
1389 // This signature supports direct call in to API function native callback
1390 // (refer to InvocationCallback in v8.h).
1391 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
1392 typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
1393
1394 // This signature supports direct call to accessor getter callback.
1395 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
1396 typedef void (*SimulatorRuntimeProfilingGetterCall)(
1397     int32_t arg0, int32_t arg1, int32_t arg2);
1398
1399 // Software interrupt instructions are used by the simulator to call into the
1400 // C-based V8 runtime. They are also used for debugging with simulator.
1401 void Simulator::SoftwareInterrupt(Instruction* instr) {
1402   // There are several instructions that could get us here,
1403   // the break_ instruction, or several variants of traps. All
1404   // Are "SPECIAL" class opcode, and are distinuished by function.
1405   int32_t func = instr->FunctionFieldRaw();
1406   uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;
1407
1408   // We first check if we met a call_rt_redirected.
1409   if (instr->InstructionBits() == rtCallRedirInstr) {
1410     Redirection* redirection = Redirection::FromSwiInstruction(instr);
1411     int32_t arg0 = get_register(a0);
1412     int32_t arg1 = get_register(a1);
1413     int32_t arg2 = get_register(a2);
1414     int32_t arg3 = get_register(a3);
1415
1416     int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1417     // Args 4 and 5 are on the stack after the reserved space for args 0..3.
1418     int32_t arg4 = stack_pointer[4];
1419     int32_t arg5 = stack_pointer[5];
1420
1421     bool fp_call =
1422          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1423          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1424          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1425          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1426
1427     if (!IsMipsSoftFloatABI) {
1428       // With the hard floating point calling convention, double
1429       // arguments are passed in FPU registers. Fetch the arguments
1430       // from there and call the builtin using soft floating point
1431       // convention.
1432       switch (redirection->type()) {
1433       case ExternalReference::BUILTIN_FP_FP_CALL:
1434       case ExternalReference::BUILTIN_COMPARE_CALL:
1435         arg0 = get_fpu_register(f12);
1436         arg1 = get_fpu_register(f13);
1437         arg2 = get_fpu_register(f14);
1438         arg3 = get_fpu_register(f15);
1439         break;
1440       case ExternalReference::BUILTIN_FP_CALL:
1441         arg0 = get_fpu_register(f12);
1442         arg1 = get_fpu_register(f13);
1443         break;
1444       case ExternalReference::BUILTIN_FP_INT_CALL:
1445         arg0 = get_fpu_register(f12);
1446         arg1 = get_fpu_register(f13);
1447         arg2 = get_register(a2);
1448         break;
1449       default:
1450         break;
1451       }
1452     }
1453
1454     // This is dodgy but it works because the C entry stubs are never moved.
1455     // See comment in codegen-arm.cc and bug 1242173.
1456     int32_t saved_ra = get_register(ra);
1457
1458     intptr_t external =
1459           reinterpret_cast<intptr_t>(redirection->external_function());
1460
1461     // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
1462     // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
1463     // simulator. Soft-float has additional abstraction of ExternalReference,
1464     // to support serialization.
1465     if (fp_call) {
1466       double dval0, dval1;  // one or two double parameters
1467       int32_t ival;         // zero or one integer parameters
1468       int64_t iresult = 0;  // integer return value
1469       double dresult = 0;   // double return value
1470       GetFpArgs(&dval0, &dval1, &ival);
1471       SimulatorRuntimeCall generic_target =
1472           reinterpret_cast<SimulatorRuntimeCall>(external);
1473       if (::v8::internal::FLAG_trace_sim) {
1474         switch (redirection->type()) {
1475           case ExternalReference::BUILTIN_FP_FP_CALL:
1476           case ExternalReference::BUILTIN_COMPARE_CALL:
1477             PrintF("Call to host function at %p with args %f, %f",
1478                    FUNCTION_ADDR(generic_target), dval0, dval1);
1479             break;
1480           case ExternalReference::BUILTIN_FP_CALL:
1481             PrintF("Call to host function at %p with arg %f",
1482                 FUNCTION_ADDR(generic_target), dval0);
1483             break;
1484           case ExternalReference::BUILTIN_FP_INT_CALL:
1485             PrintF("Call to host function at %p with args %f, %d",
1486                    FUNCTION_ADDR(generic_target), dval0, ival);
1487             break;
1488           default:
1489             UNREACHABLE();
1490             break;
1491         }
1492       }
1493       switch (redirection->type()) {
1494       case ExternalReference::BUILTIN_COMPARE_CALL: {
1495         SimulatorRuntimeCompareCall target =
1496           reinterpret_cast<SimulatorRuntimeCompareCall>(external);
1497         iresult = target(dval0, dval1);
1498         set_register(v0, static_cast<int32_t>(iresult));
1499         set_register(v1, static_cast<int32_t>(iresult >> 32));
1500         break;
1501       }
1502       case ExternalReference::BUILTIN_FP_FP_CALL: {
1503         SimulatorRuntimeFPFPCall target =
1504           reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
1505         dresult = target(dval0, dval1);
1506         SetFpResult(dresult);
1507         break;
1508       }
1509       case ExternalReference::BUILTIN_FP_CALL: {
1510         SimulatorRuntimeFPCall target =
1511           reinterpret_cast<SimulatorRuntimeFPCall>(external);
1512         dresult = target(dval0);
1513         SetFpResult(dresult);
1514         break;
1515       }
1516       case ExternalReference::BUILTIN_FP_INT_CALL: {
1517         SimulatorRuntimeFPIntCall target =
1518           reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
1519         dresult = target(dval0, ival);
1520         SetFpResult(dresult);
1521         break;
1522       }
1523       default:
1524         UNREACHABLE();
1525         break;
1526       }
1527       if (::v8::internal::FLAG_trace_sim) {
1528         switch (redirection->type()) {
1529         case ExternalReference::BUILTIN_COMPARE_CALL:
1530           PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
1531           break;
1532         case ExternalReference::BUILTIN_FP_FP_CALL:
1533         case ExternalReference::BUILTIN_FP_CALL:
1534         case ExternalReference::BUILTIN_FP_INT_CALL:
1535           PrintF("Returned %f\n", dresult);
1536           break;
1537         default:
1538           UNREACHABLE();
1539           break;
1540         }
1541       }
1542     } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1543       if (::v8::internal::FLAG_trace_sim) {
1544         PrintF("Call to host function at %p args %08x\n",
1545             reinterpret_cast<void*>(external), arg0);
1546       }
1547       SimulatorRuntimeDirectApiCall target =
1548           reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
1549       target(arg0);
1550     } else if (
1551         redirection->type() == ExternalReference::PROFILING_API_CALL) {
1552       if (::v8::internal::FLAG_trace_sim) {
1553         PrintF("Call to host function at %p args %08x %08x\n",
1554             reinterpret_cast<void*>(external), arg0, arg1);
1555       }
1556       SimulatorRuntimeProfilingApiCall target =
1557           reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
1558       target(arg0, arg1);
1559     } else if (
1560         redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
1561       if (::v8::internal::FLAG_trace_sim) {
1562         PrintF("Call to host function at %p args %08x %08x\n",
1563             reinterpret_cast<void*>(external), arg0, arg1);
1564       }
1565       SimulatorRuntimeDirectGetterCall target =
1566           reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
1567       target(arg0, arg1);
1568     } else if (
1569         redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
1570       if (::v8::internal::FLAG_trace_sim) {
1571         PrintF("Call to host function at %p args %08x %08x %08x\n",
1572             reinterpret_cast<void*>(external), arg0, arg1, arg2);
1573       }
1574       SimulatorRuntimeProfilingGetterCall target =
1575           reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
1576       target(arg0, arg1, arg2);
1577     } else {
1578       SimulatorRuntimeCall target =
1579                   reinterpret_cast<SimulatorRuntimeCall>(external);
1580       if (::v8::internal::FLAG_trace_sim) {
1581         PrintF(
1582             "Call to host function at %p "
1583             "args %08x, %08x, %08x, %08x, %08x, %08x\n",
1584             FUNCTION_ADDR(target),
1585             arg0,
1586             arg1,
1587             arg2,
1588             arg3,
1589             arg4,
1590             arg5);
1591       }
1592       int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
1593       set_register(v0, static_cast<int32_t>(result));
1594       set_register(v1, static_cast<int32_t>(result >> 32));
1595     }
1596     if (::v8::internal::FLAG_trace_sim) {
1597       PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0));
1598     }
1599     set_register(ra, saved_ra);
1600     set_pc(get_register(ra));
1601
1602   } else if (func == BREAK && code <= kMaxStopCode) {
1603     if (IsWatchpoint(code)) {
1604       PrintWatchpoint(code);
1605     } else {
1606       IncreaseStopCounter(code);
1607       HandleStop(code, instr);
1608     }
1609   } else {
1610     // All remaining break_ codes, and all traps are handled here.
1611     MipsDebugger dbg(this);
1612     dbg.Debug();
1613   }
1614 }
1615
1616
1617 // Stop helper functions.
1618 bool Simulator::IsWatchpoint(uint32_t code) {
1619   return (code <= kMaxWatchpointCode);
1620 }
1621
1622
1623 void Simulator::PrintWatchpoint(uint32_t code) {
1624   MipsDebugger dbg(this);
1625   ++break_count_;
1626   PrintF("\n---- break %d marker: %3d  (instr count: %8d) ----------"
1627          "----------------------------------",
1628          code, break_count_, icount_);
1629   dbg.PrintAllRegs();  // Print registers and continue running.
1630 }
1631
1632
1633 void Simulator::HandleStop(uint32_t code, Instruction* instr) {
1634   // Stop if it is enabled, otherwise go on jumping over the stop
1635   // and the message address.
1636   if (IsEnabledStop(code)) {
1637     MipsDebugger dbg(this);
1638     dbg.Stop(instr);
1639   } else {
1640     set_pc(get_pc() + 2 * Instruction::kInstrSize);
1641   }
1642 }
1643
1644
1645 bool Simulator::IsStopInstruction(Instruction* instr) {
1646   int32_t func = instr->FunctionFieldRaw();
1647   uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
1648   return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
1649 }
1650
1651
1652 bool Simulator::IsEnabledStop(uint32_t code) {
1653   ASSERT(code <= kMaxStopCode);
1654   ASSERT(code > kMaxWatchpointCode);
1655   return !(watched_stops_[code].count & kStopDisabledBit);
1656 }
1657
1658
1659 void Simulator::EnableStop(uint32_t code) {
1660   if (!IsEnabledStop(code)) {
1661     watched_stops_[code].count &= ~kStopDisabledBit;
1662   }
1663 }
1664
1665
1666 void Simulator::DisableStop(uint32_t code) {
1667   if (IsEnabledStop(code)) {
1668     watched_stops_[code].count |= kStopDisabledBit;
1669   }
1670 }
1671
1672
1673 void Simulator::IncreaseStopCounter(uint32_t code) {
1674   ASSERT(code <= kMaxStopCode);
1675   if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
1676     PrintF("Stop counter for code %i has overflowed.\n"
1677            "Enabling this code and reseting the counter to 0.\n", code);
1678     watched_stops_[code].count = 0;
1679     EnableStop(code);
1680   } else {
1681     watched_stops_[code].count++;
1682   }
1683 }
1684
1685
1686 // Print a stop status.
1687 void Simulator::PrintStopInfo(uint32_t code) {
1688   if (code <= kMaxWatchpointCode) {
1689     PrintF("That is a watchpoint, not a stop.\n");
1690     return;
1691   } else if (code > kMaxStopCode) {
1692     PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
1693     return;
1694   }
1695   const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled";
1696   int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
1697   // Don't print the state of unused breakpoints.
1698   if (count != 0) {
1699     if (watched_stops_[code].desc) {
1700       PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
1701              code, code, state, count, watched_stops_[code].desc);
1702     } else {
1703       PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
1704              code, code, state, count);
1705     }
1706   }
1707 }
1708
1709
1710 void Simulator::SignalExceptions() {
1711   for (int i = 1; i < kNumExceptions; i++) {
1712     if (exceptions[i] != 0) {
1713       V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i);
1714     }
1715   }
1716 }
1717
1718
1719 // Handle execution based on instruction types.
1720
1721 void Simulator::ConfigureTypeRegister(Instruction* instr,
1722                                       int32_t& alu_out,
1723                                       int64_t& i64hilo,
1724                                       uint64_t& u64hilo,
1725                                       int32_t& next_pc,
1726                                       int32_t& return_addr_reg,
1727                                       bool& do_interrupt) {
1728   // Every local variable declared here needs to be const.
1729   // This is to make sure that changed values are sent back to
1730   // DecodeTypeRegister correctly.
1731
1732   // Instruction fields.
1733   const Opcode   op     = instr->OpcodeFieldRaw();
1734   const int32_t  rs_reg = instr->RsValue();
1735   const int32_t  rs     = get_register(rs_reg);
1736   const uint32_t rs_u   = static_cast<uint32_t>(rs);
1737   const int32_t  rt_reg = instr->RtValue();
1738   const int32_t  rt     = get_register(rt_reg);
1739   const uint32_t rt_u   = static_cast<uint32_t>(rt);
1740   const int32_t  rd_reg = instr->RdValue();
1741   const uint32_t sa     = instr->SaValue();
1742
1743   const int32_t  fs_reg = instr->FsValue();
1744
1745
1746   // ---------- Configuration.
1747   switch (op) {
1748     case COP1:    // Coprocessor instructions.
1749       switch (instr->RsFieldRaw()) {
1750         case BC1:   // Handled in DecodeTypeImmed, should never come here.
1751           UNREACHABLE();
1752           break;
1753         case CFC1:
1754           // At the moment only FCSR is supported.
1755           ASSERT(fs_reg == kFCSRRegister);
1756           alu_out = FCSR_;
1757           break;
1758         case MFC1:
1759           alu_out = get_fpu_register(fs_reg);
1760           break;
1761         case MFHC1:
1762           UNIMPLEMENTED_MIPS();
1763           break;
1764         case CTC1:
1765         case MTC1:
1766         case MTHC1:
1767           // Do the store in the execution step.
1768           break;
1769         case S:
1770         case D:
1771         case W:
1772         case L:
1773         case PS:
1774           // Do everything in the execution step.
1775           break;
1776         default:
1777           UNIMPLEMENTED_MIPS();
1778       };
1779       break;
1780     case COP1X:
1781       break;
1782     case SPECIAL:
1783       switch (instr->FunctionFieldRaw()) {
1784         case JR:
1785         case JALR:
1786           next_pc = get_register(instr->RsValue());
1787           return_addr_reg = instr->RdValue();
1788           break;
1789         case SLL:
1790           alu_out = rt << sa;
1791           break;
1792         case SRL:
1793           if (rs_reg == 0) {
1794             // Regular logical right shift of a word by a fixed number of
1795             // bits instruction. RS field is always equal to 0.
1796             alu_out = rt_u >> sa;
1797           } else {
1798             // Logical right-rotate of a word by a fixed number of bits. This
1799             // is special case of SRL instruction, added in MIPS32 Release 2.
1800             // RS field is equal to 00001.
1801             alu_out = (rt_u >> sa) | (rt_u << (32 - sa));
1802           }
1803           break;
1804         case SRA:
1805           alu_out = rt >> sa;
1806           break;
1807         case SLLV:
1808           alu_out = rt << rs;
1809           break;
1810         case SRLV:
1811           if (sa == 0) {
1812             // Regular logical right-shift of a word by a variable number of
1813             // bits instruction. SA field is always equal to 0.
1814             alu_out = rt_u >> rs;
1815           } else {
1816             // Logical right-rotate of a word by a variable number of bits.
1817             // This is special case od SRLV instruction, added in MIPS32
1818             // Release 2. SA field is equal to 00001.
1819             alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u));
1820           }
1821           break;
1822         case SRAV:
1823           alu_out = rt >> rs;
1824           break;
1825         case MFHI:
1826           alu_out = get_register(HI);
1827           break;
1828         case MFLO:
1829           alu_out = get_register(LO);
1830           break;
1831         case MULT:
1832           i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt);
1833           break;
1834         case MULTU:
1835           u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u);
1836           break;
1837         case ADD:
1838           if (HaveSameSign(rs, rt)) {
1839             if (rs > 0) {
1840               exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
1841             } else if (rs < 0) {
1842               exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
1843             }
1844           }
1845           alu_out = rs + rt;
1846           break;
1847         case ADDU:
1848           alu_out = rs + rt;
1849           break;
1850         case SUB:
1851           if (!HaveSameSign(rs, rt)) {
1852             if (rs > 0) {
1853               exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt);
1854             } else if (rs < 0) {
1855               exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt);
1856             }
1857           }
1858           alu_out = rs - rt;
1859           break;
1860         case SUBU:
1861           alu_out = rs - rt;
1862           break;
1863         case AND:
1864           alu_out = rs & rt;
1865           break;
1866         case OR:
1867           alu_out = rs | rt;
1868           break;
1869         case XOR:
1870           alu_out = rs ^ rt;
1871           break;
1872         case NOR:
1873           alu_out = ~(rs | rt);
1874           break;
1875         case SLT:
1876           alu_out = rs < rt ? 1 : 0;
1877           break;
1878         case SLTU:
1879           alu_out = rs_u < rt_u ? 1 : 0;
1880           break;
1881         // Break and trap instructions.
1882         case BREAK:
1883
1884           do_interrupt = true;
1885           break;
1886         case TGE:
1887           do_interrupt = rs >= rt;
1888           break;
1889         case TGEU:
1890           do_interrupt = rs_u >= rt_u;
1891           break;
1892         case TLT:
1893           do_interrupt = rs < rt;
1894           break;
1895         case TLTU:
1896           do_interrupt = rs_u < rt_u;
1897           break;
1898         case TEQ:
1899           do_interrupt = rs == rt;
1900           break;
1901         case TNE:
1902           do_interrupt = rs != rt;
1903           break;
1904         case MOVN:
1905         case MOVZ:
1906         case MOVCI:
1907           // No action taken on decode.
1908           break;
1909         case DIV:
1910         case DIVU:
1911           // div and divu never raise exceptions.
1912           break;
1913         default:
1914           UNREACHABLE();
1915       };
1916       break;
1917     case SPECIAL2:
1918       switch (instr->FunctionFieldRaw()) {
1919         case MUL:
1920           alu_out = rs_u * rt_u;  // Only the lower 32 bits are kept.
1921           break;
1922         case CLZ:
1923           alu_out = __builtin_clz(rs_u);
1924           break;
1925         default:
1926           UNREACHABLE();
1927       };
1928       break;
1929     case SPECIAL3:
1930       switch (instr->FunctionFieldRaw()) {
1931         case INS: {   // Mips32r2 instruction.
1932           // Interpret rd field as 5-bit msb of insert.
1933           uint16_t msb = rd_reg;
1934           // Interpret sa field as 5-bit lsb of insert.
1935           uint16_t lsb = sa;
1936           uint16_t size = msb - lsb + 1;
1937           uint32_t mask = (1 << size) - 1;
1938           alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
1939           break;
1940         }
1941         case EXT: {   // Mips32r2 instruction.
1942           // Interpret rd field as 5-bit msb of extract.
1943           uint16_t msb = rd_reg;
1944           // Interpret sa field as 5-bit lsb of extract.
1945           uint16_t lsb = sa;
1946           uint16_t size = msb + 1;
1947           uint32_t mask = (1 << size) - 1;
1948           alu_out = (rs_u & (mask << lsb)) >> lsb;
1949           break;
1950         }
1951         default:
1952           UNREACHABLE();
1953       };
1954       break;
1955     default:
1956       UNREACHABLE();
1957   };
1958 }
1959
1960
1961 void Simulator::DecodeTypeRegister(Instruction* instr) {
1962   // Instruction fields.
1963   const Opcode   op     = instr->OpcodeFieldRaw();
1964   const int32_t  rs_reg = instr->RsValue();
1965   const int32_t  rs     = get_register(rs_reg);
1966   const uint32_t rs_u   = static_cast<uint32_t>(rs);
1967   const int32_t  rt_reg = instr->RtValue();
1968   const int32_t  rt     = get_register(rt_reg);
1969   const uint32_t rt_u   = static_cast<uint32_t>(rt);
1970   const int32_t  rd_reg = instr->RdValue();
1971
1972   const int32_t  fr_reg = instr->FrValue();
1973   const int32_t  fs_reg = instr->FsValue();
1974   const int32_t  ft_reg = instr->FtValue();
1975   const int32_t  fd_reg = instr->FdValue();
1976   int64_t  i64hilo = 0;
1977   uint64_t u64hilo = 0;
1978
1979   // ALU output.
1980   // It should not be used as is. Instructions using it should always
1981   // initialize it first.
1982   int32_t alu_out = 0x12345678;
1983
1984   // For break and trap instructions.
1985   bool do_interrupt = false;
1986
1987   // For jr and jalr.
1988   // Get current pc.
1989   int32_t current_pc = get_pc();
1990   // Next pc
1991   int32_t next_pc = 0;
1992   int32_t return_addr_reg = 31;
1993
1994   // Set up the variables if needed before executing the instruction.
1995   ConfigureTypeRegister(instr,
1996                         alu_out,
1997                         i64hilo,
1998                         u64hilo,
1999                         next_pc,
2000                         return_addr_reg,
2001                         do_interrupt);
2002
2003   // ---------- Raise exceptions triggered.
2004   SignalExceptions();
2005
2006   // ---------- Execution.
2007   switch (op) {
2008     case COP1:
2009       switch (instr->RsFieldRaw()) {
2010         case BC1:   // Branch on coprocessor condition.
2011           UNREACHABLE();
2012           break;
2013         case CFC1:
2014           set_register(rt_reg, alu_out);
2015         case MFC1:
2016           set_register(rt_reg, alu_out);
2017           break;
2018         case MFHC1:
2019           UNIMPLEMENTED_MIPS();
2020           break;
2021         case CTC1:
2022           // At the moment only FCSR is supported.
2023           ASSERT(fs_reg == kFCSRRegister);
2024           FCSR_ = registers_[rt_reg];
2025           break;
2026         case MTC1:
2027           FPUregisters_[fs_reg] = registers_[rt_reg];
2028           break;
2029         case MTHC1:
2030           UNIMPLEMENTED_MIPS();
2031           break;
2032         case S:
2033           float f;
2034           switch (instr->FunctionFieldRaw()) {
2035             case CVT_D_S:
2036               f = get_fpu_register_float(fs_reg);
2037               set_fpu_register_double(fd_reg, static_cast<double>(f));
2038               break;
2039             case CVT_W_S:
2040             case CVT_L_S:
2041             case TRUNC_W_S:
2042             case TRUNC_L_S:
2043             case ROUND_W_S:
2044             case ROUND_L_S:
2045             case FLOOR_W_S:
2046             case FLOOR_L_S:
2047             case CEIL_W_S:
2048             case CEIL_L_S:
2049             case CVT_PS_S:
2050               UNIMPLEMENTED_MIPS();
2051               break;
2052             default:
2053               UNREACHABLE();
2054           }
2055           break;
2056         case D:
2057           double ft, fs;
2058           uint32_t cc, fcsr_cc;
2059           int64_t  i64;
2060           fs = get_fpu_register_double(fs_reg);
2061           ft = get_fpu_register_double(ft_reg);
2062           cc = instr->FCccValue();
2063           fcsr_cc = get_fcsr_condition_bit(cc);
2064           switch (instr->FunctionFieldRaw()) {
2065             case ADD_D:
2066               set_fpu_register_double(fd_reg, fs + ft);
2067               break;
2068             case SUB_D:
2069               set_fpu_register_double(fd_reg, fs - ft);
2070               break;
2071             case MUL_D:
2072               set_fpu_register_double(fd_reg, fs * ft);
2073               break;
2074             case DIV_D:
2075               set_fpu_register_double(fd_reg, fs / ft);
2076               break;
2077             case ABS_D:
2078               set_fpu_register_double(fd_reg, fabs(fs));
2079               break;
2080             case MOV_D:
2081               set_fpu_register_double(fd_reg, fs);
2082               break;
2083             case NEG_D:
2084               set_fpu_register_double(fd_reg, -fs);
2085               break;
2086             case SQRT_D:
2087               set_fpu_register_double(fd_reg, sqrt(fs));
2088               break;
2089             case C_UN_D:
2090               set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2091               break;
2092             case C_EQ_D:
2093               set_fcsr_bit(fcsr_cc, (fs == ft));
2094               break;
2095             case C_UEQ_D:
2096               set_fcsr_bit(fcsr_cc,
2097                            (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2098               break;
2099             case C_OLT_D:
2100               set_fcsr_bit(fcsr_cc, (fs < ft));
2101               break;
2102             case C_ULT_D:
2103               set_fcsr_bit(fcsr_cc,
2104                            (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
2105               break;
2106             case C_OLE_D:
2107               set_fcsr_bit(fcsr_cc, (fs <= ft));
2108               break;
2109             case C_ULE_D:
2110               set_fcsr_bit(fcsr_cc,
2111                            (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2112               break;
2113             case CVT_W_D:   // Convert double to word.
2114               // Rounding modes are not yet supported.
2115               ASSERT((FCSR_ & 3) == 0);
2116               // In rounding mode 0 it should behave like ROUND.
2117             case ROUND_W_D:  // Round double to word (round half to even).
2118               {
2119                 double rounded = std::floor(fs + 0.5);
2120                 int32_t result = static_cast<int32_t>(rounded);
2121                 if ((result & 1) != 0 && result - fs == 0.5) {
2122                   // If the number is halfway between two integers,
2123                   // round to the even one.
2124                   result--;
2125                 }
2126                 set_fpu_register(fd_reg, result);
2127                 if (set_fcsr_round_error(fs, rounded)) {
2128                   set_fpu_register(fd_reg, kFPUInvalidResult);
2129                 }
2130               }
2131               break;
2132             case TRUNC_W_D:  // Truncate double to word (round towards 0).
2133               {
2134                 double rounded = trunc(fs);
2135                 int32_t result = static_cast<int32_t>(rounded);
2136                 set_fpu_register(fd_reg, result);
2137                 if (set_fcsr_round_error(fs, rounded)) {
2138                   set_fpu_register(fd_reg, kFPUInvalidResult);
2139                 }
2140               }
2141               break;
2142             case FLOOR_W_D:  // Round double to word towards negative infinity.
2143               {
2144                 double rounded = std::floor(fs);
2145                 int32_t result = static_cast<int32_t>(rounded);
2146                 set_fpu_register(fd_reg, result);
2147                 if (set_fcsr_round_error(fs, rounded)) {
2148                   set_fpu_register(fd_reg, kFPUInvalidResult);
2149                 }
2150               }
2151               break;
2152             case CEIL_W_D:  // Round double to word towards positive infinity.
2153               {
2154                 double rounded = std::ceil(fs);
2155                 int32_t result = static_cast<int32_t>(rounded);
2156                 set_fpu_register(fd_reg, result);
2157                 if (set_fcsr_round_error(fs, rounded)) {
2158                   set_fpu_register(fd_reg, kFPUInvalidResult);
2159                 }
2160               }
2161               break;
2162             case CVT_S_D:  // Convert double to float (single).
2163               set_fpu_register_float(fd_reg, static_cast<float>(fs));
2164               break;
2165             case CVT_L_D: {  // Mips32r2: Truncate double to 64-bit long-word.
2166               double rounded = trunc(fs);
2167               i64 = static_cast<int64_t>(rounded);
2168               set_fpu_register(fd_reg, i64 & 0xffffffff);
2169               set_fpu_register(fd_reg + 1, i64 >> 32);
2170               break;
2171             }
2172             case TRUNC_L_D: {  // Mips32r2 instruction.
2173               double rounded = trunc(fs);
2174               i64 = static_cast<int64_t>(rounded);
2175               set_fpu_register(fd_reg, i64 & 0xffffffff);
2176               set_fpu_register(fd_reg + 1, i64 >> 32);
2177               break;
2178             }
2179             case ROUND_L_D: {  // Mips32r2 instruction.
2180               double rounded =
2181                   fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5);
2182               i64 = static_cast<int64_t>(rounded);
2183               set_fpu_register(fd_reg, i64 & 0xffffffff);
2184               set_fpu_register(fd_reg + 1, i64 >> 32);
2185               break;
2186             }
2187             case FLOOR_L_D:  // Mips32r2 instruction.
2188               i64 = static_cast<int64_t>(std::floor(fs));
2189               set_fpu_register(fd_reg, i64 & 0xffffffff);
2190               set_fpu_register(fd_reg + 1, i64 >> 32);
2191               break;
2192             case CEIL_L_D:  // Mips32r2 instruction.
2193               i64 = static_cast<int64_t>(std::ceil(fs));
2194               set_fpu_register(fd_reg, i64 & 0xffffffff);
2195               set_fpu_register(fd_reg + 1, i64 >> 32);
2196               break;
2197             case C_F_D:
2198               UNIMPLEMENTED_MIPS();
2199               break;
2200             default:
2201               UNREACHABLE();
2202           }
2203           break;
2204         case W:
2205           switch (instr->FunctionFieldRaw()) {
2206             case CVT_S_W:   // Convert word to float (single).
2207               alu_out = get_fpu_register(fs_reg);
2208               set_fpu_register_float(fd_reg, static_cast<float>(alu_out));
2209               break;
2210             case CVT_D_W:   // Convert word to double.
2211               alu_out = get_fpu_register(fs_reg);
2212               set_fpu_register_double(fd_reg, static_cast<double>(alu_out));
2213               break;
2214             default:
2215               UNREACHABLE();
2216           };
2217           break;
2218         case L:
2219           switch (instr->FunctionFieldRaw()) {
2220           case CVT_D_L:  // Mips32r2 instruction.
2221             // Watch the signs here, we want 2 32-bit vals
2222             // to make a sign-64.
2223             i64 = static_cast<uint32_t>(get_fpu_register(fs_reg));
2224             i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32;
2225             set_fpu_register_double(fd_reg, static_cast<double>(i64));
2226             break;
2227             case CVT_S_L:
2228               UNIMPLEMENTED_MIPS();
2229               break;
2230             default:
2231               UNREACHABLE();
2232           }
2233           break;
2234         case PS:
2235           break;
2236         default:
2237           UNREACHABLE();
2238       };
2239       break;
2240     case COP1X:
2241       switch (instr->FunctionFieldRaw()) {
2242         case MADD_D:
2243           double fr, ft, fs;
2244           fr = get_fpu_register_double(fr_reg);
2245           fs = get_fpu_register_double(fs_reg);
2246           ft = get_fpu_register_double(ft_reg);
2247           set_fpu_register_double(fd_reg, fs * ft + fr);
2248           break;
2249         default:
2250           UNREACHABLE();
2251       };
2252       break;
2253     case SPECIAL:
2254       switch (instr->FunctionFieldRaw()) {
2255         case JR: {
2256           Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
2257               current_pc+Instruction::kInstrSize);
2258           BranchDelayInstructionDecode(branch_delay_instr);
2259           set_pc(next_pc);
2260           pc_modified_ = true;
2261           break;
2262         }
2263         case JALR: {
2264           Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
2265               current_pc+Instruction::kInstrSize);
2266           BranchDelayInstructionDecode(branch_delay_instr);
2267           set_register(return_addr_reg,
2268                        current_pc + 2 * Instruction::kInstrSize);
2269           set_pc(next_pc);
2270           pc_modified_ = true;
2271           break;
2272         }
2273         // Instructions using HI and LO registers.
2274         case MULT:
2275           set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
2276           set_register(HI, static_cast<int32_t>(i64hilo >> 32));
2277           break;
2278         case MULTU:
2279           set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
2280           set_register(HI, static_cast<int32_t>(u64hilo >> 32));
2281           break;
2282         case DIV:
2283           // Divide by zero and overflow was not checked in the configuration
2284           // step - div and divu do not raise exceptions. On division by 0
2285           // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1),
2286           // return INT_MIN which is what the hardware does.
2287           if (rs == INT_MIN && rt == -1) {
2288             set_register(LO, INT_MIN);
2289             set_register(HI, 0);
2290           } else if (rt != 0) {
2291             set_register(LO, rs / rt);
2292             set_register(HI, rs % rt);
2293           }
2294           break;
2295         case DIVU:
2296           if (rt_u != 0) {
2297             set_register(LO, rs_u / rt_u);
2298             set_register(HI, rs_u % rt_u);
2299           }
2300           break;
2301         // Break and trap instructions.
2302         case BREAK:
2303         case TGE:
2304         case TGEU:
2305         case TLT:
2306         case TLTU:
2307         case TEQ:
2308         case TNE:
2309           if (do_interrupt) {
2310             SoftwareInterrupt(instr);
2311           }
2312           break;
2313         // Conditional moves.
2314         case MOVN:
2315           if (rt) set_register(rd_reg, rs);
2316           break;
2317         case MOVCI: {
2318           uint32_t cc = instr->FBccValue();
2319           uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
2320           if (instr->Bit(16)) {  // Read Tf bit.
2321             if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
2322           } else {
2323             if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
2324           }
2325           break;
2326         }
2327         case MOVZ:
2328           if (!rt) set_register(rd_reg, rs);
2329           break;
2330         default:  // For other special opcodes we do the default operation.
2331           set_register(rd_reg, alu_out);
2332       };
2333       break;
2334     case SPECIAL2:
2335       switch (instr->FunctionFieldRaw()) {
2336         case MUL:
2337           set_register(rd_reg, alu_out);
2338           // HI and LO are UNPREDICTABLE after the operation.
2339           set_register(LO, Unpredictable);
2340           set_register(HI, Unpredictable);
2341           break;
2342         default:  // For other special2 opcodes we do the default operation.
2343           set_register(rd_reg, alu_out);
2344       }
2345       break;
2346     case SPECIAL3:
2347       switch (instr->FunctionFieldRaw()) {
2348         case INS:
2349           // Ins instr leaves result in Rt, rather than Rd.
2350           set_register(rt_reg, alu_out);
2351           break;
2352         case EXT:
2353           // Ext instr leaves result in Rt, rather than Rd.
2354           set_register(rt_reg, alu_out);
2355           break;
2356         default:
2357           UNREACHABLE();
2358       };
2359       break;
2360     // Unimplemented opcodes raised an error in the configuration step before,
2361     // so we can use the default here to set the destination register in common
2362     // cases.
2363     default:
2364       set_register(rd_reg, alu_out);
2365   };
2366 }
2367
2368
2369 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
2370 void Simulator::DecodeTypeImmediate(Instruction* instr) {
2371   // Instruction fields.
2372   Opcode   op     = instr->OpcodeFieldRaw();
2373   int32_t  rs     = get_register(instr->RsValue());
2374   uint32_t rs_u   = static_cast<uint32_t>(rs);
2375   int32_t  rt_reg = instr->RtValue();  // Destination register.
2376   int32_t  rt     = get_register(rt_reg);
2377   int16_t  imm16  = instr->Imm16Value();
2378
2379   int32_t  ft_reg = instr->FtValue();  // Destination register.
2380
2381   // Zero extended immediate.
2382   uint32_t  oe_imm16 = 0xffff & imm16;
2383   // Sign extended immediate.
2384   int32_t   se_imm16 = imm16;
2385
2386   // Get current pc.
2387   int32_t current_pc = get_pc();
2388   // Next pc.
2389   int32_t next_pc = bad_ra;
2390
2391   // Used for conditional branch instructions.
2392   bool do_branch = false;
2393   bool execute_branch_delay_instruction = false;
2394
2395   // Used for arithmetic instructions.
2396   int32_t alu_out = 0;
2397   // Floating point.
2398   double fp_out = 0.0;
2399   uint32_t cc, cc_value, fcsr_cc;
2400
2401   // Used for memory instructions.
2402   int32_t addr = 0x0;
2403   // Value to be written in memory.
2404   uint32_t mem_value = 0x0;
2405
2406   // ---------- Configuration (and execution for REGIMM).
2407   switch (op) {
2408     // ------------- COP1. Coprocessor instructions.
2409     case COP1:
2410       switch (instr->RsFieldRaw()) {
2411         case BC1:   // Branch on coprocessor condition.
2412           cc = instr->FBccValue();
2413           fcsr_cc = get_fcsr_condition_bit(cc);
2414           cc_value = test_fcsr_bit(fcsr_cc);
2415           do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
2416           execute_branch_delay_instruction = true;
2417           // Set next_pc.
2418           if (do_branch) {
2419             next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2420           } else {
2421             next_pc = current_pc + kBranchReturnOffset;
2422           }
2423           break;
2424         default:
2425           UNREACHABLE();
2426       };
2427       break;
2428     // ------------- REGIMM class.
2429     case REGIMM:
2430       switch (instr->RtFieldRaw()) {
2431         case BLTZ:
2432           do_branch = (rs  < 0);
2433           break;
2434         case BLTZAL:
2435           do_branch = rs  < 0;
2436           break;
2437         case BGEZ:
2438           do_branch = rs >= 0;
2439           break;
2440         case BGEZAL:
2441           do_branch = rs >= 0;
2442           break;
2443         default:
2444           UNREACHABLE();
2445       };
2446       switch (instr->RtFieldRaw()) {
2447         case BLTZ:
2448         case BLTZAL:
2449         case BGEZ:
2450         case BGEZAL:
2451           // Branch instructions common part.
2452           execute_branch_delay_instruction = true;
2453           // Set next_pc.
2454           if (do_branch) {
2455             next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2456             if (instr->IsLinkingInstruction()) {
2457               set_register(31, current_pc + kBranchReturnOffset);
2458             }
2459           } else {
2460             next_pc = current_pc + kBranchReturnOffset;
2461           }
2462         default:
2463           break;
2464         };
2465     break;  // case REGIMM.
2466     // ------------- Branch instructions.
2467     // When comparing to zero, the encoding of rt field is always 0, so we don't
2468     // need to replace rt with zero.
2469     case BEQ:
2470       do_branch = (rs == rt);
2471       break;
2472     case BNE:
2473       do_branch = rs != rt;
2474       break;
2475     case BLEZ:
2476       do_branch = rs <= 0;
2477       break;
2478     case BGTZ:
2479       do_branch = rs  > 0;
2480       break;
2481     // ------------- Arithmetic instructions.
2482     case ADDI:
2483       if (HaveSameSign(rs, se_imm16)) {
2484         if (rs > 0) {
2485           exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
2486         } else if (rs < 0) {
2487           exceptions[kIntegerUnderflow] =
2488               rs < (Registers::kMinValue - se_imm16);
2489         }
2490       }
2491       alu_out = rs + se_imm16;
2492       break;
2493     case ADDIU:
2494       alu_out = rs + se_imm16;
2495       break;
2496     case SLTI:
2497       alu_out = (rs < se_imm16) ? 1 : 0;
2498       break;
2499     case SLTIU:
2500       alu_out = (rs_u < static_cast<uint32_t>(se_imm16)) ? 1 : 0;
2501       break;
2502     case ANDI:
2503         alu_out = rs & oe_imm16;
2504       break;
2505     case ORI:
2506         alu_out = rs | oe_imm16;
2507       break;
2508     case XORI:
2509         alu_out = rs ^ oe_imm16;
2510       break;
2511     case LUI:
2512         alu_out = (oe_imm16 << 16);
2513       break;
2514     // ------------- Memory instructions.
2515     case LB:
2516       addr = rs + se_imm16;
2517       alu_out = ReadB(addr);
2518       break;
2519     case LH:
2520       addr = rs + se_imm16;
2521       alu_out = ReadH(addr, instr);
2522       break;
2523     case LWL: {
2524       // al_offset is offset of the effective address within an aligned word.
2525       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
2526       uint8_t byte_shift = kPointerAlignmentMask - al_offset;
2527       uint32_t mask = (1 << byte_shift * 8) - 1;
2528       addr = rs + se_imm16 - al_offset;
2529       alu_out = ReadW(addr, instr);
2530       alu_out <<= byte_shift * 8;
2531       alu_out |= rt & mask;
2532       break;
2533     }
2534     case LW:
2535       addr = rs + se_imm16;
2536       alu_out = ReadW(addr, instr);
2537       break;
2538     case LBU:
2539       addr = rs + se_imm16;
2540       alu_out = ReadBU(addr);
2541       break;
2542     case LHU:
2543       addr = rs + se_imm16;
2544       alu_out = ReadHU(addr, instr);
2545       break;
2546     case LWR: {
2547       // al_offset is offset of the effective address within an aligned word.
2548       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
2549       uint8_t byte_shift = kPointerAlignmentMask - al_offset;
2550       uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
2551       addr = rs + se_imm16 - al_offset;
2552       alu_out = ReadW(addr, instr);
2553       alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
2554       alu_out |= rt & mask;
2555       break;
2556     }
2557     case SB:
2558       addr = rs + se_imm16;
2559       break;
2560     case SH:
2561       addr = rs + se_imm16;
2562       break;
2563     case SWL: {
2564       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
2565       uint8_t byte_shift = kPointerAlignmentMask - al_offset;
2566       uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
2567       addr = rs + se_imm16 - al_offset;
2568       mem_value = ReadW(addr, instr) & mask;
2569       mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
2570       break;
2571     }
2572     case SW:
2573       addr = rs + se_imm16;
2574       break;
2575     case SWR: {
2576       uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
2577       uint32_t mask = (1 << al_offset * 8) - 1;
2578       addr = rs + se_imm16 - al_offset;
2579       mem_value = ReadW(addr, instr);
2580       mem_value = (rt << al_offset * 8) | (mem_value & mask);
2581       break;
2582     }
2583     case LWC1:
2584       addr = rs + se_imm16;
2585       alu_out = ReadW(addr, instr);
2586       break;
2587     case LDC1:
2588       addr = rs + se_imm16;
2589       fp_out = ReadD(addr, instr);
2590       break;
2591     case SWC1:
2592     case SDC1:
2593       addr = rs + se_imm16;
2594       break;
2595     default:
2596       UNREACHABLE();
2597   };
2598
2599   // ---------- Raise exceptions triggered.
2600   SignalExceptions();
2601
2602   // ---------- Execution.
2603   switch (op) {
2604     // ------------- Branch instructions.
2605     case BEQ:
2606     case BNE:
2607     case BLEZ:
2608     case BGTZ:
2609       // Branch instructions common part.
2610       execute_branch_delay_instruction = true;
2611       // Set next_pc.
2612       if (do_branch) {
2613         next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2614         if (instr->IsLinkingInstruction()) {
2615           set_register(31, current_pc + 2* Instruction::kInstrSize);
2616         }
2617       } else {
2618         next_pc = current_pc + 2 * Instruction::kInstrSize;
2619       }
2620       break;
2621     // ------------- Arithmetic instructions.
2622     case ADDI:
2623     case ADDIU:
2624     case SLTI:
2625     case SLTIU:
2626     case ANDI:
2627     case ORI:
2628     case XORI:
2629     case LUI:
2630       set_register(rt_reg, alu_out);
2631       break;
2632     // ------------- Memory instructions.
2633     case LB:
2634     case LH:
2635     case LWL:
2636     case LW:
2637     case LBU:
2638     case LHU:
2639     case LWR:
2640       set_register(rt_reg, alu_out);
2641       break;
2642     case SB:
2643       WriteB(addr, static_cast<int8_t>(rt));
2644       break;
2645     case SH:
2646       WriteH(addr, static_cast<uint16_t>(rt), instr);
2647       break;
2648     case SWL:
2649       WriteW(addr, mem_value, instr);
2650       break;
2651     case SW:
2652       WriteW(addr, rt, instr);
2653       break;
2654     case SWR:
2655       WriteW(addr, mem_value, instr);
2656       break;
2657     case LWC1:
2658       set_fpu_register(ft_reg, alu_out);
2659       break;
2660     case LDC1:
2661       set_fpu_register_double(ft_reg, fp_out);
2662       break;
2663     case SWC1:
2664       addr = rs + se_imm16;
2665       WriteW(addr, get_fpu_register(ft_reg), instr);
2666       break;
2667     case SDC1:
2668       addr = rs + se_imm16;
2669       WriteD(addr, get_fpu_register_double(ft_reg), instr);
2670       break;
2671     default:
2672       break;
2673   };
2674
2675
2676   if (execute_branch_delay_instruction) {
2677     // Execute branch delay slot
2678     // We don't check for end_sim_pc. First it should not be met as the current
2679     // pc is valid. Secondly a jump should always execute its branch delay slot.
2680     Instruction* branch_delay_instr =
2681       reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize);
2682     BranchDelayInstructionDecode(branch_delay_instr);
2683   }
2684
2685   // If needed update pc after the branch delay execution.
2686   if (next_pc != bad_ra) {
2687     set_pc(next_pc);
2688   }
2689 }
2690
2691
2692 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
2693 void Simulator::DecodeTypeJump(Instruction* instr) {
2694   // Get current pc.
2695   int32_t current_pc = get_pc();
2696   // Get unchanged bits of pc.
2697   int32_t pc_high_bits = current_pc & 0xf0000000;
2698   // Next pc.
2699   int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);
2700
2701   // Execute branch delay slot.
2702   // We don't check for end_sim_pc. First it should not be met as the current pc
2703   // is valid. Secondly a jump should always execute its branch delay slot.
2704   Instruction* branch_delay_instr =
2705       reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
2706   BranchDelayInstructionDecode(branch_delay_instr);
2707
2708   // Update pc and ra if necessary.
2709   // Do this after the branch delay execution.
2710   if (instr->IsLinkingInstruction()) {
2711     set_register(31, current_pc + 2 * Instruction::kInstrSize);
2712   }
2713   set_pc(next_pc);
2714   pc_modified_ = true;
2715 }
2716
2717
2718 // Executes the current instruction.
2719 void Simulator::InstructionDecode(Instruction* instr) {
2720   if (v8::internal::FLAG_check_icache) {
2721     CheckICache(isolate_->simulator_i_cache(), instr);
2722   }
2723   pc_modified_ = false;
2724   if (::v8::internal::FLAG_trace_sim) {
2725     disasm::NameConverter converter;
2726     disasm::Disassembler dasm(converter);
2727     // Use a reasonably large buffer.
2728     v8::internal::EmbeddedVector<char, 256> buffer;
2729     dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
2730     PrintF("  0x%08x  %s\n", reinterpret_cast<intptr_t>(instr),
2731         buffer.start());
2732   }
2733
2734   switch (instr->InstructionType()) {
2735     case Instruction::kRegisterType:
2736       DecodeTypeRegister(instr);
2737       break;
2738     case Instruction::kImmediateType:
2739       DecodeTypeImmediate(instr);
2740       break;
2741     case Instruction::kJumpType:
2742       DecodeTypeJump(instr);
2743       break;
2744     default:
2745       UNSUPPORTED();
2746   }
2747   if (!pc_modified_) {
2748     set_register(pc, reinterpret_cast<int32_t>(instr) +
2749                  Instruction::kInstrSize);
2750   }
2751 }
2752
2753
2754
2755 void Simulator::Execute() {
2756   // Get the PC to simulate. Cannot use the accessor here as we need the
2757   // raw PC value and not the one used as input to arithmetic instructions.
2758   int program_counter = get_pc();
2759   if (::v8::internal::FLAG_stop_sim_at == 0) {
2760     // Fast version of the dispatch loop without checking whether the simulator
2761     // should be stopping at a particular executed instruction.
2762     while (program_counter != end_sim_pc) {
2763       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
2764       icount_++;
2765       InstructionDecode(instr);
2766       program_counter = get_pc();
2767     }
2768   } else {
2769     // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
2770     // we reach the particular instuction count.
2771     while (program_counter != end_sim_pc) {
2772       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
2773       icount_++;
2774       if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
2775         MipsDebugger dbg(this);
2776         dbg.Debug();
2777       } else {
2778         InstructionDecode(instr);
2779       }
2780       program_counter = get_pc();
2781     }
2782   }
2783 }
2784
2785
2786 void Simulator::CallInternal(byte* entry) {
2787   // Prepare to execute the code at entry.
2788   set_register(pc, reinterpret_cast<int32_t>(entry));
2789   // Put down marker for end of simulation. The simulator will stop simulation
2790   // when the PC reaches this value. By saving the "end simulation" value into
2791   // the LR the simulation stops when returning to this call point.
2792   set_register(ra, end_sim_pc);
2793
2794   // Remember the values of callee-saved registers.
2795   // The code below assumes that r9 is not used as sb (static base) in
2796   // simulator code and therefore is regarded as a callee-saved register.
2797   int32_t s0_val = get_register(s0);
2798   int32_t s1_val = get_register(s1);
2799   int32_t s2_val = get_register(s2);
2800   int32_t s3_val = get_register(s3);
2801   int32_t s4_val = get_register(s4);
2802   int32_t s5_val = get_register(s5);
2803   int32_t s6_val = get_register(s6);
2804   int32_t s7_val = get_register(s7);
2805   int32_t gp_val = get_register(gp);
2806   int32_t sp_val = get_register(sp);
2807   int32_t fp_val = get_register(fp);
2808
2809   // Set up the callee-saved registers with a known value. To be able to check
2810   // that they are preserved properly across JS execution.
2811   int32_t callee_saved_value = icount_;
2812   set_register(s0, callee_saved_value);
2813   set_register(s1, callee_saved_value);
2814   set_register(s2, callee_saved_value);
2815   set_register(s3, callee_saved_value);
2816   set_register(s4, callee_saved_value);
2817   set_register(s5, callee_saved_value);
2818   set_register(s6, callee_saved_value);
2819   set_register(s7, callee_saved_value);
2820   set_register(gp, callee_saved_value);
2821   set_register(fp, callee_saved_value);
2822
2823   // Start the simulation.
2824   Execute();
2825
2826   // Check that the callee-saved registers have been preserved.
2827   CHECK_EQ(callee_saved_value, get_register(s0));
2828   CHECK_EQ(callee_saved_value, get_register(s1));
2829   CHECK_EQ(callee_saved_value, get_register(s2));
2830   CHECK_EQ(callee_saved_value, get_register(s3));
2831   CHECK_EQ(callee_saved_value, get_register(s4));
2832   CHECK_EQ(callee_saved_value, get_register(s5));
2833   CHECK_EQ(callee_saved_value, get_register(s6));
2834   CHECK_EQ(callee_saved_value, get_register(s7));
2835   CHECK_EQ(callee_saved_value, get_register(gp));
2836   CHECK_EQ(callee_saved_value, get_register(fp));
2837
2838   // Restore callee-saved registers with the original value.
2839   set_register(s0, s0_val);
2840   set_register(s1, s1_val);
2841   set_register(s2, s2_val);
2842   set_register(s3, s3_val);
2843   set_register(s4, s4_val);
2844   set_register(s5, s5_val);
2845   set_register(s6, s6_val);
2846   set_register(s7, s7_val);
2847   set_register(gp, gp_val);
2848   set_register(sp, sp_val);
2849   set_register(fp, fp_val);
2850 }
2851
2852
2853 int32_t Simulator::Call(byte* entry, int argument_count, ...) {
2854   va_list parameters;
2855   va_start(parameters, argument_count);
2856   // Set up arguments.
2857
2858   // First four arguments passed in registers.
2859   ASSERT(argument_count >= 4);
2860   set_register(a0, va_arg(parameters, int32_t));
2861   set_register(a1, va_arg(parameters, int32_t));
2862   set_register(a2, va_arg(parameters, int32_t));
2863   set_register(a3, va_arg(parameters, int32_t));
2864
2865   // Remaining arguments passed on stack.
2866   int original_stack = get_register(sp);
2867   // Compute position of stack on entry to generated code.
2868   int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t)
2869                                     - kCArgsSlotsSize);
2870   if (OS::ActivationFrameAlignment() != 0) {
2871     entry_stack &= -OS::ActivationFrameAlignment();
2872   }
2873   // Store remaining arguments on stack, from low to high memory.
2874   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
2875   for (int i = 4; i < argument_count; i++) {
2876     stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t);
2877   }
2878   va_end(parameters);
2879   set_register(sp, entry_stack);
2880
2881   CallInternal(entry);
2882
2883   // Pop stack passed arguments.
2884   CHECK_EQ(entry_stack, get_register(sp));
2885   set_register(sp, original_stack);
2886
2887   int32_t result = get_register(v0);
2888   return result;
2889 }
2890
2891
2892 double Simulator::CallFP(byte* entry, double d0, double d1) {
2893   if (!IsMipsSoftFloatABI) {
2894     set_fpu_register_double(f12, d0);
2895     set_fpu_register_double(f14, d1);
2896   } else {
2897     int buffer[2];
2898     ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0));
2899     OS::MemCopy(buffer, &d0, sizeof(d0));
2900     set_dw_register(a0, buffer);
2901     OS::MemCopy(buffer, &d1, sizeof(d1));
2902     set_dw_register(a2, buffer);
2903   }
2904   CallInternal(entry);
2905   if (!IsMipsSoftFloatABI) {
2906     return get_fpu_register_double(f0);
2907   } else {
2908     return get_double_from_register_pair(v0);
2909   }
2910 }
2911
2912
2913 uintptr_t Simulator::PushAddress(uintptr_t address) {
2914   int new_sp = get_register(sp) - sizeof(uintptr_t);
2915   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
2916   *stack_slot = address;
2917   set_register(sp, new_sp);
2918   return new_sp;
2919 }
2920
2921
2922 uintptr_t Simulator::PopAddress() {
2923   int current_sp = get_register(sp);
2924   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
2925   uintptr_t address = *stack_slot;
2926   set_register(sp, current_sp + sizeof(uintptr_t));
2927   return address;
2928 }
2929
2930
2931 #undef UNSUPPORTED
2932
2933 } }  // namespace v8::internal
2934
2935 #endif  // USE_SIMULATOR
2936
2937 #endif  // V8_TARGET_ARCH_MIPS