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