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