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