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