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