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