Updated V8 from git://github.com/v8/v8.git to 57f8959fb264354ba1a2e5118db512f588917061
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / arm / simulator-arm.cc
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <stdlib.h>
29 #include <math.h>
30 #include <cstdarg>
31 #include "v8.h"
32
33 #if defined(V8_TARGET_ARCH_ARM)
34
35 #include "disasm.h"
36 #include "assembler.h"
37 #include "arm/constants-arm.h"
38 #include "arm/simulator-arm.h"
39
40 #if defined(USE_SIMULATOR)
41
42 // Only build the simulator if not compiling for real ARM hardware.
43 namespace v8 {
44 namespace internal {
45
46 // This macro provides a platform independent use of sscanf. The reason for
47 // SScanF not being implemented in a platform independent way through
48 // ::v8::internal::OS in the same way as SNPrintF is that the
49 // Windows C Run-Time Library does not provide vsscanf.
50 #define SScanF sscanf  // NOLINT
51
52 // The ArmDebugger class is used by the simulator while debugging simulated ARM
53 // code.
54 class ArmDebugger {
55  public:
56   explicit ArmDebugger(Simulator* sim) : sim_(sim) { }
57   ~ArmDebugger();
58
59   void Stop(Instruction* instr);
60   void Debug();
61
62  private:
63   static const Instr kBreakpointInstr =
64       (al | (7*B25) | (1*B24) | kBreakpoint);
65   static const Instr kNopInstr = (al | (13*B21));
66
67   Simulator* sim_;
68
69   int32_t GetRegisterValue(int regnum);
70   double GetRegisterPairDoubleValue(int regnum);
71   double GetVFPDoubleRegisterValue(int regnum);
72   bool GetValue(const char* desc, int32_t* value);
73   bool GetVFPSingleValue(const char* desc, float* value);
74   bool GetVFPDoubleValue(const char* desc, double* 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 ArmDebugger::~ArmDebugger() {
88 }
89
90
91
92 #ifdef GENERATED_CODE_COVERAGE
93 static FILE* coverage_log = NULL;
94
95
96 static void InitializeCoverage() {
97   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
98   if (file_name != NULL) {
99     coverage_log = fopen(file_name, "aw+");
100   }
101 }
102
103
104 void ArmDebugger::Stop(Instruction* instr) {
105   // Get the stop code.
106   uint32_t code = instr->SvcValue() & kStopCodeMask;
107   // Retrieve the encoded address, which comes just after this stop.
108   char** msg_address =
109     reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
110   char* msg = *msg_address;
111   ASSERT(msg != NULL);
112
113   // Update this stop description.
114   if (isWatchedStop(code) && !watched_stops[code].desc) {
115     watched_stops[code].desc = msg;
116   }
117
118   if (strlen(msg) > 0) {
119     if (coverage_log != NULL) {
120       fprintf(coverage_log, "%s\n", msg);
121       fflush(coverage_log);
122     }
123     // Overwrite the instruction and address with nops.
124     instr->SetInstructionBits(kNopInstr);
125     reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
126   }
127   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
128 }
129
130 #else  // ndef GENERATED_CODE_COVERAGE
131
132 static void InitializeCoverage() {
133 }
134
135
136 void ArmDebugger::Stop(Instruction* instr) {
137   // Get the stop code.
138   uint32_t code = instr->SvcValue() & kStopCodeMask;
139   // Retrieve the encoded address, which comes just after this stop.
140   char* msg = *reinterpret_cast<char**>(sim_->get_pc()
141                                         + Instruction::kInstrSize);
142   // Update this stop description.
143   if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) {
144     sim_->watched_stops[code].desc = msg;
145   }
146   // Print the stop message and code if it is not the default code.
147   if (code != kMaxStopCode) {
148     PrintF("Simulator hit stop %u: %s\n", code, msg);
149   } else {
150     PrintF("Simulator hit %s\n", msg);
151   }
152   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
153   Debug();
154 }
155 #endif
156
157
158 int32_t ArmDebugger::GetRegisterValue(int regnum) {
159   if (regnum == kPCRegister) {
160     return sim_->get_pc();
161   } else {
162     return sim_->get_register(regnum);
163   }
164 }
165
166
167 double ArmDebugger::GetRegisterPairDoubleValue(int regnum) {
168   return sim_->get_double_from_register_pair(regnum);
169 }
170
171
172 double ArmDebugger::GetVFPDoubleRegisterValue(int regnum) {
173   return sim_->get_double_from_d_register(regnum);
174 }
175
176
177 bool ArmDebugger::GetValue(const char* desc, int32_t* value) {
178   int regnum = Registers::Number(desc);
179   if (regnum != kNoRegister) {
180     *value = GetRegisterValue(regnum);
181     return true;
182   } else {
183     if (strncmp(desc, "0x", 2) == 0) {
184       return SScanF(desc + 2, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
185     } else {
186       return SScanF(desc, "%u", reinterpret_cast<uint32_t*>(value)) == 1;
187     }
188   }
189   return false;
190 }
191
192
193 bool ArmDebugger::GetVFPSingleValue(const char* desc, float* value) {
194   bool is_double;
195   int regnum = VFPRegisters::Number(desc, &is_double);
196   if (regnum != kNoRegister && !is_double) {
197     *value = sim_->get_float_from_s_register(regnum);
198     return true;
199   }
200   return false;
201 }
202
203
204 bool ArmDebugger::GetVFPDoubleValue(const char* desc, double* value) {
205   bool is_double;
206   int regnum = VFPRegisters::Number(desc, &is_double);
207   if (regnum != kNoRegister && is_double) {
208     *value = sim_->get_double_from_d_register(regnum);
209     return true;
210   }
211   return false;
212 }
213
214
215 bool ArmDebugger::SetBreakpoint(Instruction* breakpc) {
216   // Check if a breakpoint can be set. If not return without any side-effects.
217   if (sim_->break_pc_ != NULL) {
218     return false;
219   }
220
221   // Set the breakpoint.
222   sim_->break_pc_ = breakpc;
223   sim_->break_instr_ = breakpc->InstructionBits();
224   // Not setting the breakpoint instruction in the code itself. It will be set
225   // when the debugger shell continues.
226   return true;
227 }
228
229
230 bool ArmDebugger::DeleteBreakpoint(Instruction* breakpc) {
231   if (sim_->break_pc_ != NULL) {
232     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
233   }
234
235   sim_->break_pc_ = NULL;
236   sim_->break_instr_ = 0;
237   return true;
238 }
239
240
241 void ArmDebugger::UndoBreakpoints() {
242   if (sim_->break_pc_ != NULL) {
243     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
244   }
245 }
246
247
248 void ArmDebugger::RedoBreakpoints() {
249   if (sim_->break_pc_ != NULL) {
250     sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
251   }
252 }
253
254
255 void ArmDebugger::Debug() {
256   intptr_t last_pc = -1;
257   bool done = false;
258
259 #define COMMAND_SIZE 63
260 #define ARG_SIZE 255
261
262 #define STR(a) #a
263 #define XSTR(a) STR(a)
264
265   char cmd[COMMAND_SIZE + 1];
266   char arg1[ARG_SIZE + 1];
267   char arg2[ARG_SIZE + 1];
268   char* argv[3] = { cmd, arg1, arg2 };
269
270   // make sure to have a proper terminating character if reaching the limit
271   cmd[COMMAND_SIZE] = 0;
272   arg1[ARG_SIZE] = 0;
273   arg2[ARG_SIZE] = 0;
274
275   // Undo all set breakpoints while running in the debugger shell. This will
276   // make them invisible to all commands.
277   UndoBreakpoints();
278
279   while (!done) {
280     if (last_pc != sim_->get_pc()) {
281       disasm::NameConverter converter;
282       disasm::Disassembler dasm(converter);
283       // use a reasonably large buffer
284       v8::internal::EmbeddedVector<char, 256> buffer;
285       dasm.InstructionDecode(buffer,
286                              reinterpret_cast<byte*>(sim_->get_pc()));
287       PrintF("  0x%08x  %s\n", sim_->get_pc(), buffer.start());
288       last_pc = sim_->get_pc();
289     }
290     char* line = ReadLine("sim> ");
291     if (line == NULL) {
292       break;
293     } else {
294       char* last_input = sim_->last_debugger_input();
295       if (strcmp(line, "\n") == 0 && last_input != NULL) {
296         line = last_input;
297       } else {
298         // Ownership is transferred to sim_;
299         sim_->set_last_debugger_input(line);
300       }
301       // Use sscanf to parse the individual parts of the command line. At the
302       // moment no command expects more than two parameters.
303       int argc = SScanF(line,
304                         "%" XSTR(COMMAND_SIZE) "s "
305                         "%" XSTR(ARG_SIZE) "s "
306                         "%" XSTR(ARG_SIZE) "s",
307                         cmd, arg1, arg2);
308       if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
309         sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
310       } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
311         // Execute the one instruction we broke at with breakpoints disabled.
312         sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
313         // Leave the debugger shell.
314         done = true;
315       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
316         if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) {
317           int32_t value;
318           float svalue;
319           double dvalue;
320           if (strcmp(arg1, "all") == 0) {
321             for (int i = 0; i < kNumRegisters; i++) {
322               value = GetRegisterValue(i);
323               PrintF("%3s: 0x%08x %10d", Registers::Name(i), value, value);
324               if ((argc == 3 && strcmp(arg2, "fp") == 0) &&
325                   i < 8 &&
326                   (i % 2) == 0) {
327                 dvalue = GetRegisterPairDoubleValue(i);
328                 PrintF(" (%f)\n", dvalue);
329               } else {
330                 PrintF("\n");
331               }
332             }
333             for (int i = 0; i < kNumVFPDoubleRegisters; i++) {
334               dvalue = GetVFPDoubleRegisterValue(i);
335               uint64_t as_words = BitCast<uint64_t>(dvalue);
336               PrintF("%3s: %f 0x%08x %08x\n",
337                      VFPRegisters::Name(i, true),
338                      dvalue,
339                      static_cast<uint32_t>(as_words >> 32),
340                      static_cast<uint32_t>(as_words & 0xffffffff));
341             }
342           } else {
343             if (GetValue(arg1, &value)) {
344               PrintF("%s: 0x%08x %d \n", arg1, value, value);
345             } else if (GetVFPSingleValue(arg1, &svalue)) {
346               uint32_t as_word = BitCast<uint32_t>(svalue);
347               PrintF("%s: %f 0x%08x\n", arg1, svalue, as_word);
348             } else if (GetVFPDoubleValue(arg1, &dvalue)) {
349               uint64_t as_words = BitCast<uint64_t>(dvalue);
350               PrintF("%s: %f 0x%08x %08x\n",
351                      arg1,
352                      dvalue,
353                      static_cast<uint32_t>(as_words >> 32),
354                      static_cast<uint32_t>(as_words & 0xffffffff));
355             } else {
356               PrintF("%s unrecognized\n", arg1);
357             }
358           }
359         } else {
360           PrintF("print <register>\n");
361         }
362       } else if ((strcmp(cmd, "po") == 0)
363                  || (strcmp(cmd, "printobject") == 0)) {
364         if (argc == 2) {
365           int32_t value;
366           if (GetValue(arg1, &value)) {
367             Object* obj = reinterpret_cast<Object*>(value);
368             PrintF("%s: \n", arg1);
369 #ifdef DEBUG
370             obj->PrintLn();
371 #else
372             obj->ShortPrint();
373             PrintF("\n");
374 #endif
375           } else {
376             PrintF("%s unrecognized\n", arg1);
377           }
378         } else {
379           PrintF("printobject <value>\n");
380         }
381       } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
382         int32_t* cur = NULL;
383         int32_t* end = NULL;
384         int next_arg = 1;
385
386         if (strcmp(cmd, "stack") == 0) {
387           cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp));
388         } else {  // "mem"
389           int32_t value;
390           if (!GetValue(arg1, &value)) {
391             PrintF("%s unrecognized\n", arg1);
392             continue;
393           }
394           cur = reinterpret_cast<int32_t*>(value);
395           next_arg++;
396         }
397
398         int32_t words;
399         if (argc == next_arg) {
400           words = 10;
401         } else if (argc == next_arg + 1) {
402           if (!GetValue(argv[next_arg], &words)) {
403             words = 10;
404           }
405         }
406         end = cur + words;
407
408         while (cur < end) {
409           PrintF("  0x%08x:  0x%08x %10d",
410                  reinterpret_cast<intptr_t>(cur), *cur, *cur);
411           HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
412           int value = *cur;
413           Heap* current_heap = v8::internal::Isolate::Current()->heap();
414           if (current_heap->Contains(obj) || ((value & 1) == 0)) {
415             PrintF(" (");
416             if ((value & 1) == 0) {
417               PrintF("smi %d", value / 2);
418             } else {
419               obj->ShortPrint();
420             }
421             PrintF(")");
422           }
423           PrintF("\n");
424           cur++;
425         }
426       } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
427         disasm::NameConverter converter;
428         disasm::Disassembler dasm(converter);
429         // use a reasonably large buffer
430         v8::internal::EmbeddedVector<char, 256> buffer;
431
432         byte* prev = NULL;
433         byte* cur = NULL;
434         byte* end = NULL;
435
436         if (argc == 1) {
437           cur = reinterpret_cast<byte*>(sim_->get_pc());
438           end = cur + (10 * Instruction::kInstrSize);
439         } else if (argc == 2) {
440           int regnum = Registers::Number(arg1);
441           if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
442             // The argument is an address or a register name.
443             int32_t value;
444             if (GetValue(arg1, &value)) {
445               cur = reinterpret_cast<byte*>(value);
446               // Disassemble 10 instructions at <arg1>.
447               end = cur + (10 * Instruction::kInstrSize);
448             }
449           } else {
450             // The argument is the number of instructions.
451             int32_t value;
452             if (GetValue(arg1, &value)) {
453               cur = reinterpret_cast<byte*>(sim_->get_pc());
454               // Disassemble <arg1> instructions.
455               end = cur + (value * Instruction::kInstrSize);
456             }
457           }
458         } else {
459           int32_t value1;
460           int32_t value2;
461           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
462             cur = reinterpret_cast<byte*>(value1);
463             end = cur + (value2 * Instruction::kInstrSize);
464           }
465         }
466
467         while (cur < end) {
468           prev = cur;
469           cur += dasm.InstructionDecode(buffer, cur);
470           PrintF("  0x%08x  %s\n",
471                  reinterpret_cast<intptr_t>(prev), buffer.start());
472         }
473       } else if (strcmp(cmd, "gdb") == 0) {
474         PrintF("relinquishing control to gdb\n");
475         v8::internal::OS::DebugBreak();
476         PrintF("regaining control from gdb\n");
477       } else if (strcmp(cmd, "break") == 0) {
478         if (argc == 2) {
479           int32_t value;
480           if (GetValue(arg1, &value)) {
481             if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
482               PrintF("setting breakpoint failed\n");
483             }
484           } else {
485             PrintF("%s unrecognized\n", arg1);
486           }
487         } else {
488           PrintF("break <address>\n");
489         }
490       } else if (strcmp(cmd, "del") == 0) {
491         if (!DeleteBreakpoint(NULL)) {
492           PrintF("deleting breakpoint failed\n");
493         }
494       } else if (strcmp(cmd, "flags") == 0) {
495         PrintF("N flag: %d; ", sim_->n_flag_);
496         PrintF("Z flag: %d; ", sim_->z_flag_);
497         PrintF("C flag: %d; ", sim_->c_flag_);
498         PrintF("V flag: %d\n", sim_->v_flag_);
499         PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_);
500         PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_);
501         PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_);
502         PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_);
503         PrintF("INEXACT flag: %d;\n", sim_->inexact_vfp_flag_);
504       } else if (strcmp(cmd, "stop") == 0) {
505         int32_t value;
506         intptr_t stop_pc = sim_->get_pc() - 2 * Instruction::kInstrSize;
507         Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
508         Instruction* msg_address =
509           reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize);
510         if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
511           // Remove the current stop.
512           if (sim_->isStopInstruction(stop_instr)) {
513             stop_instr->SetInstructionBits(kNopInstr);
514             msg_address->SetInstructionBits(kNopInstr);
515           } else {
516             PrintF("Not at debugger stop.\n");
517           }
518         } else if (argc == 3) {
519           // Print information about all/the specified breakpoint(s).
520           if (strcmp(arg1, "info") == 0) {
521             if (strcmp(arg2, "all") == 0) {
522               PrintF("Stop information:\n");
523               for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
524                 sim_->PrintStopInfo(i);
525               }
526             } else if (GetValue(arg2, &value)) {
527               sim_->PrintStopInfo(value);
528             } else {
529               PrintF("Unrecognized argument.\n");
530             }
531           } else if (strcmp(arg1, "enable") == 0) {
532             // Enable all/the specified breakpoint(s).
533             if (strcmp(arg2, "all") == 0) {
534               for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
535                 sim_->EnableStop(i);
536               }
537             } else if (GetValue(arg2, &value)) {
538               sim_->EnableStop(value);
539             } else {
540               PrintF("Unrecognized argument.\n");
541             }
542           } else if (strcmp(arg1, "disable") == 0) {
543             // Disable all/the specified breakpoint(s).
544             if (strcmp(arg2, "all") == 0) {
545               for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
546                 sim_->DisableStop(i);
547               }
548             } else if (GetValue(arg2, &value)) {
549               sim_->DisableStop(value);
550             } else {
551               PrintF("Unrecognized argument.\n");
552             }
553           }
554         } else {
555           PrintF("Wrong usage. Use help command for more information.\n");
556         }
557       } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
558         ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
559         PrintF("Trace of executed instructions is %s\n",
560                ::v8::internal::FLAG_trace_sim ? "on" : "off");
561       } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
562         PrintF("cont\n");
563         PrintF("  continue execution (alias 'c')\n");
564         PrintF("stepi\n");
565         PrintF("  step one instruction (alias 'si')\n");
566         PrintF("print <register>\n");
567         PrintF("  print register content (alias 'p')\n");
568         PrintF("  use register name 'all' to print all registers\n");
569         PrintF("  add argument 'fp' to print register pair double values\n");
570         PrintF("printobject <register>\n");
571         PrintF("  print an object from a register (alias 'po')\n");
572         PrintF("flags\n");
573         PrintF("  print flags\n");
574         PrintF("stack [<words>]\n");
575         PrintF("  dump stack content, default dump 10 words)\n");
576         PrintF("mem <address> [<words>]\n");
577         PrintF("  dump memory content, default dump 10 words)\n");
578         PrintF("disasm [<instructions>]\n");
579         PrintF("disasm [<address/register>]\n");
580         PrintF("disasm [[<address/register>] <instructions>]\n");
581         PrintF("  disassemble code, default is 10 instructions\n");
582         PrintF("  from pc (alias 'di')\n");
583         PrintF("gdb\n");
584         PrintF("  enter gdb\n");
585         PrintF("break <address>\n");
586         PrintF("  set a break point on the address\n");
587         PrintF("del\n");
588         PrintF("  delete the breakpoint\n");
589         PrintF("trace (alias 't')\n");
590         PrintF("  toogle the tracing of all executed statements\n");
591         PrintF("stop feature:\n");
592         PrintF("  Description:\n");
593         PrintF("    Stops are debug instructions inserted by\n");
594         PrintF("    the Assembler::stop() function.\n");
595         PrintF("    When hitting a stop, the Simulator will\n");
596         PrintF("    stop and and give control to the ArmDebugger.\n");
597         PrintF("    The first %d stop codes are watched:\n",
598                Simulator::kNumOfWatchedStops);
599         PrintF("    - They can be enabled / disabled: the Simulator\n");
600         PrintF("      will / won't stop when hitting them.\n");
601         PrintF("    - The Simulator keeps track of how many times they \n");
602         PrintF("      are met. (See the info command.) Going over a\n");
603         PrintF("      disabled stop still increases its counter. \n");
604         PrintF("  Commands:\n");
605         PrintF("    stop info all/<code> : print infos about number <code>\n");
606         PrintF("      or all stop(s).\n");
607         PrintF("    stop enable/disable all/<code> : enables / disables\n");
608         PrintF("      all or number <code> stop(s)\n");
609         PrintF("    stop unstop\n");
610         PrintF("      ignore the stop instruction at the current location\n");
611         PrintF("      from now on\n");
612       } else {
613         PrintF("Unknown command: %s\n", cmd);
614       }
615     }
616   }
617
618   // Add all the breakpoints back to stop execution and enter the debugger
619   // shell when hit.
620   RedoBreakpoints();
621
622 #undef COMMAND_SIZE
623 #undef ARG_SIZE
624
625 #undef STR
626 #undef XSTR
627 }
628
629
630 static bool ICacheMatch(void* one, void* two) {
631   ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
632   ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
633   return one == two;
634 }
635
636
637 static uint32_t ICacheHash(void* key) {
638   return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
639 }
640
641
642 static bool AllOnOnePage(uintptr_t start, int size) {
643   intptr_t start_page = (start & ~CachePage::kPageMask);
644   intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
645   return start_page == end_page;
646 }
647
648
649 void Simulator::set_last_debugger_input(char* input) {
650   DeleteArray(last_debugger_input_);
651   last_debugger_input_ = input;
652 }
653
654
655 void Simulator::FlushICache(v8::internal::HashMap* i_cache,
656                             void* start_addr,
657                             size_t size) {
658   intptr_t start = reinterpret_cast<intptr_t>(start_addr);
659   int intra_line = (start & CachePage::kLineMask);
660   start -= intra_line;
661   size += intra_line;
662   size = ((size - 1) | CachePage::kLineMask) + 1;
663   int offset = (start & CachePage::kPageMask);
664   while (!AllOnOnePage(start, size - 1)) {
665     int bytes_to_flush = CachePage::kPageSize - offset;
666     FlushOnePage(i_cache, start, bytes_to_flush);
667     start += bytes_to_flush;
668     size -= bytes_to_flush;
669     ASSERT_EQ(0, start & CachePage::kPageMask);
670     offset = 0;
671   }
672   if (size != 0) {
673     FlushOnePage(i_cache, start, size);
674   }
675 }
676
677
678 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
679   v8::internal::HashMap::Entry* entry = i_cache->Lookup(page,
680                                                         ICacheHash(page),
681                                                         true);
682   if (entry->value == NULL) {
683     CachePage* new_page = new CachePage();
684     entry->value = new_page;
685   }
686   return reinterpret_cast<CachePage*>(entry->value);
687 }
688
689
690 // Flush from start up to and not including start + size.
691 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache,
692                              intptr_t start,
693                              int size) {
694   ASSERT(size <= CachePage::kPageSize);
695   ASSERT(AllOnOnePage(start, size - 1));
696   ASSERT((start & CachePage::kLineMask) == 0);
697   ASSERT((size & CachePage::kLineMask) == 0);
698   void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
699   int offset = (start & CachePage::kPageMask);
700   CachePage* cache_page = GetCachePage(i_cache, page);
701   char* valid_bytemap = cache_page->ValidityByte(offset);
702   memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
703 }
704
705
706 void Simulator::CheckICache(v8::internal::HashMap* i_cache,
707                             Instruction* instr) {
708   intptr_t address = reinterpret_cast<intptr_t>(instr);
709   void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
710   void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
711   int offset = (address & CachePage::kPageMask);
712   CachePage* cache_page = GetCachePage(i_cache, page);
713   char* cache_valid_byte = cache_page->ValidityByte(offset);
714   bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
715   char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
716   if (cache_hit) {
717     // Check that the data in memory matches the contents of the I-cache.
718     CHECK(memcmp(reinterpret_cast<void*>(instr),
719                  cache_page->CachedData(offset),
720                  Instruction::kInstrSize) == 0);
721   } else {
722     // Cache miss.  Load memory into the cache.
723     memcpy(cached_line, line, CachePage::kLineLength);
724     *cache_valid_byte = CachePage::LINE_VALID;
725   }
726 }
727
728
729 void Simulator::Initialize(Isolate* isolate) {
730   if (isolate->simulator_initialized()) return;
731   isolate->set_simulator_initialized(true);
732   ::v8::internal::ExternalReference::set_redirector(isolate,
733                                                     &RedirectExternalReference);
734 }
735
736
737 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
738   i_cache_ = isolate_->simulator_i_cache();
739   if (i_cache_ == NULL) {
740     i_cache_ = new v8::internal::HashMap(&ICacheMatch);
741     isolate_->set_simulator_i_cache(i_cache_);
742   }
743   Initialize(isolate);
744   // Set up simulator support first. Some of this information is needed to
745   // setup the architecture state.
746   size_t stack_size = 1 * 1024*1024;  // allocate 1MB for stack
747   stack_ = reinterpret_cast<char*>(malloc(stack_size));
748   pc_modified_ = false;
749   icount_ = 0;
750   break_pc_ = NULL;
751   break_instr_ = 0;
752
753   // Set up architecture state.
754   // All registers are initialized to zero to start with.
755   for (int i = 0; i < num_registers; i++) {
756     registers_[i] = 0;
757   }
758   n_flag_ = false;
759   z_flag_ = false;
760   c_flag_ = false;
761   v_flag_ = false;
762
763   // Initializing VFP registers.
764   // All registers are initialized to zero to start with
765   // even though s_registers_ & d_registers_ share the same
766   // physical registers in the target.
767   for (int i = 0; i < num_s_registers; i++) {
768     vfp_register[i] = 0;
769   }
770   n_flag_FPSCR_ = false;
771   z_flag_FPSCR_ = false;
772   c_flag_FPSCR_ = false;
773   v_flag_FPSCR_ = false;
774   FPSCR_rounding_mode_ = RZ;
775
776   inv_op_vfp_flag_ = false;
777   div_zero_vfp_flag_ = false;
778   overflow_vfp_flag_ = false;
779   underflow_vfp_flag_ = false;
780   inexact_vfp_flag_ = false;
781
782   // The sp is initialized to point to the bottom (high address) of the
783   // allocated stack area. To be safe in potential stack underflows we leave
784   // some buffer below.
785   registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64;
786   // The lr and pc are initialized to a known bad value that will cause an
787   // access violation if the simulator ever tries to execute it.
788   registers_[pc] = bad_lr;
789   registers_[lr] = bad_lr;
790   InitializeCoverage();
791
792   last_debugger_input_ = NULL;
793 }
794
795
796 // When the generated code calls an external reference we need to catch that in
797 // the simulator.  The external reference will be a function compiled for the
798 // host architecture.  We need to call that function instead of trying to
799 // execute it with the simulator.  We do that by redirecting the external
800 // reference to a svc (Supervisor Call) instruction that is handled by
801 // the simulator.  We write the original destination of the jump just at a known
802 // offset from the svc instruction so the simulator knows what to call.
803 class Redirection {
804  public:
805   Redirection(void* external_function, ExternalReference::Type type)
806       : external_function_(external_function),
807         swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
808         type_(type),
809         next_(NULL) {
810     Isolate* isolate = Isolate::Current();
811     next_ = isolate->simulator_redirection();
812     Simulator::current(isolate)->
813         FlushICache(isolate->simulator_i_cache(),
814                     reinterpret_cast<void*>(&swi_instruction_),
815                     Instruction::kInstrSize);
816     isolate->set_simulator_redirection(this);
817   }
818
819   void* address_of_swi_instruction() {
820     return reinterpret_cast<void*>(&swi_instruction_);
821   }
822
823   void* external_function() { return external_function_; }
824   ExternalReference::Type type() { return type_; }
825
826   static Redirection* Get(void* external_function,
827                           ExternalReference::Type type) {
828     Isolate* isolate = Isolate::Current();
829     Redirection* current = isolate->simulator_redirection();
830     for (; current != NULL; current = current->next_) {
831       if (current->external_function_ == external_function) return current;
832     }
833     return new Redirection(external_function, type);
834   }
835
836   static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
837     char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
838     char* addr_of_redirection =
839         addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
840     return reinterpret_cast<Redirection*>(addr_of_redirection);
841   }
842
843  private:
844   void* external_function_;
845   uint32_t swi_instruction_;
846   ExternalReference::Type type_;
847   Redirection* next_;
848 };
849
850
851 void* Simulator::RedirectExternalReference(void* external_function,
852                                            ExternalReference::Type type) {
853   Redirection* redirection = Redirection::Get(external_function, type);
854   return redirection->address_of_swi_instruction();
855 }
856
857
858 // Get the active Simulator for the current thread.
859 Simulator* Simulator::current(Isolate* isolate) {
860   v8::internal::Isolate::PerIsolateThreadData* isolate_data =
861       isolate->FindOrAllocatePerThreadDataForThisThread();
862   ASSERT(isolate_data != NULL);
863
864   Simulator* sim = isolate_data->simulator();
865   if (sim == NULL) {
866     // TODO(146): delete the simulator object when a thread/isolate goes away.
867     sim = new Simulator(isolate);
868     isolate_data->set_simulator(sim);
869   }
870   return sim;
871 }
872
873
874 // Sets the register in the architecture state. It will also deal with updating
875 // Simulator internal state for special registers such as PC.
876 void Simulator::set_register(int reg, int32_t value) {
877   ASSERT((reg >= 0) && (reg < num_registers));
878   if (reg == pc) {
879     pc_modified_ = true;
880   }
881   registers_[reg] = value;
882 }
883
884
885 // Get the register from the architecture state. This function does handle
886 // the special case of accessing the PC register.
887 int32_t Simulator::get_register(int reg) const {
888   ASSERT((reg >= 0) && (reg < num_registers));
889   // Stupid code added to avoid bug in GCC.
890   // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
891   if (reg >= num_registers) return 0;
892   // End stupid code.
893   return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
894 }
895
896
897 double Simulator::get_double_from_register_pair(int reg) {
898   ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0));
899
900   double dm_val = 0.0;
901   // Read the bits from the unsigned integer register_[] array
902   // into the double precision floating point value and return it.
903   char buffer[2 * sizeof(vfp_register[0])];
904   memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
905   memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
906   return(dm_val);
907 }
908
909
910 void Simulator::set_dw_register(int dreg, const int* dbl) {
911   ASSERT((dreg >= 0) && (dreg < num_d_registers));
912   registers_[dreg] = dbl[0];
913   registers_[dreg + 1] = dbl[1];
914 }
915
916
917 // Raw access to the PC register.
918 void Simulator::set_pc(int32_t value) {
919   pc_modified_ = true;
920   registers_[pc] = value;
921 }
922
923
924 bool Simulator::has_bad_pc() const {
925   return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc));
926 }
927
928
929 // Raw access to the PC register without the special adjustment when reading.
930 int32_t Simulator::get_pc() const {
931   return registers_[pc];
932 }
933
934
935 // Getting from and setting into VFP registers.
936 void Simulator::set_s_register(int sreg, unsigned int value) {
937   ASSERT((sreg >= 0) && (sreg < num_s_registers));
938   vfp_register[sreg] = value;
939 }
940
941
942 unsigned int Simulator::get_s_register(int sreg) const {
943   ASSERT((sreg >= 0) && (sreg < num_s_registers));
944   return vfp_register[sreg];
945 }
946
947
948 void Simulator::set_s_register_from_float(int sreg, const float flt) {
949   ASSERT((sreg >= 0) && (sreg < num_s_registers));
950   // Read the bits from the single precision floating point value
951   // into the unsigned integer element of vfp_register[] given by index=sreg.
952   char buffer[sizeof(vfp_register[0])];
953   memcpy(buffer, &flt, sizeof(vfp_register[0]));
954   memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
955 }
956
957
958 void Simulator::set_s_register_from_sinteger(int sreg, const int sint) {
959   ASSERT((sreg >= 0) && (sreg < num_s_registers));
960   // Read the bits from the integer value into the unsigned integer element of
961   // vfp_register[] given by index=sreg.
962   char buffer[sizeof(vfp_register[0])];
963   memcpy(buffer, &sint, sizeof(vfp_register[0]));
964   memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
965 }
966
967
968 void Simulator::set_d_register_from_double(int dreg, const double& dbl) {
969   ASSERT((dreg >= 0) && (dreg < num_d_registers));
970   // Read the bits from the double precision floating point value into the two
971   // consecutive unsigned integer elements of vfp_register[] given by index
972   // 2*sreg and 2*sreg+1.
973   char buffer[2 * sizeof(vfp_register[0])];
974   memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
975   memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
976 }
977
978
979 float Simulator::get_float_from_s_register(int sreg) {
980   ASSERT((sreg >= 0) && (sreg < num_s_registers));
981
982   float sm_val = 0.0;
983   // Read the bits from the unsigned integer vfp_register[] array
984   // into the single precision floating point value and return it.
985   char buffer[sizeof(vfp_register[0])];
986   memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
987   memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
988   return(sm_val);
989 }
990
991
992 int Simulator::get_sinteger_from_s_register(int sreg) {
993   ASSERT((sreg >= 0) && (sreg < num_s_registers));
994
995   int sm_val = 0;
996   // Read the bits from the unsigned integer vfp_register[] array
997   // into the single precision floating point value and return it.
998   char buffer[sizeof(vfp_register[0])];
999   memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
1000   memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
1001   return(sm_val);
1002 }
1003
1004
1005 double Simulator::get_double_from_d_register(int dreg) {
1006   ASSERT((dreg >= 0) && (dreg < num_d_registers));
1007
1008   double dm_val = 0.0;
1009   // Read the bits from the unsigned integer vfp_register[] array
1010   // into the double precision floating point value and return it.
1011   char buffer[2 * sizeof(vfp_register[0])];
1012   memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
1013   memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
1014   return(dm_val);
1015 }
1016
1017
1018 // For use in calls that take two double values, constructed either
1019 // from r0-r3 or d0 and d1.
1020 void Simulator::GetFpArgs(double* x, double* y) {
1021   if (use_eabi_hardfloat()) {
1022     *x = vfp_register[0];
1023     *y = vfp_register[1];
1024   } else {
1025     // We use a char buffer to get around the strict-aliasing rules which
1026     // otherwise allow the compiler to optimize away the copy.
1027     char buffer[sizeof(*x)];
1028     // Registers 0 and 1 -> x.
1029     memcpy(buffer, registers_, sizeof(*x));
1030     memcpy(x, buffer, sizeof(*x));
1031     // Registers 2 and 3 -> y.
1032     memcpy(buffer, registers_ + 2, sizeof(*y));
1033     memcpy(y, buffer, sizeof(*y));
1034   }
1035 }
1036
1037 // For use in calls that take one double value, constructed either
1038 // from r0 and r1 or d0.
1039 void Simulator::GetFpArgs(double* x) {
1040   if (use_eabi_hardfloat()) {
1041     *x = vfp_register[0];
1042   } else {
1043     // We use a char buffer to get around the strict-aliasing rules which
1044     // otherwise allow the compiler to optimize away the copy.
1045     char buffer[sizeof(*x)];
1046     // Registers 0 and 1 -> x.
1047     memcpy(buffer, registers_, sizeof(*x));
1048     memcpy(x, buffer, sizeof(*x));
1049   }
1050 }
1051
1052
1053 // For use in calls that take one double value constructed either
1054 // from r0 and r1 or d0 and one integer value.
1055 void Simulator::GetFpArgs(double* x, int32_t* y) {
1056   if (use_eabi_hardfloat()) {
1057     *x = vfp_register[0];
1058     *y = registers_[1];
1059   } else {
1060     // We use a char buffer to get around the strict-aliasing rules which
1061     // otherwise allow the compiler to optimize away the copy.
1062     char buffer[sizeof(*x)];
1063     // Registers 0 and 1 -> x.
1064     memcpy(buffer, registers_, sizeof(*x));
1065     memcpy(x, buffer, sizeof(*x));
1066     // Register 2 -> y.
1067     memcpy(buffer, registers_ + 2, sizeof(*y));
1068     memcpy(y, buffer, sizeof(*y));
1069   }
1070 }
1071
1072
1073 // The return value is either in r0/r1 or d0.
1074 void Simulator::SetFpResult(const double& result) {
1075   if (use_eabi_hardfloat()) {
1076     char buffer[2 * sizeof(vfp_register[0])];
1077     memcpy(buffer, &result, sizeof(buffer));
1078     // Copy result to d0.
1079     memcpy(vfp_register, buffer, sizeof(buffer));
1080   } else {
1081     char buffer[2 * sizeof(registers_[0])];
1082     memcpy(buffer, &result, sizeof(buffer));
1083     // Copy result to r0 and r1.
1084     memcpy(registers_, buffer, sizeof(buffer));
1085   }
1086 }
1087
1088
1089 void Simulator::TrashCallerSaveRegisters() {
1090   // We don't trash the registers with the return value.
1091   registers_[2] = 0x50Bad4U;
1092   registers_[3] = 0x50Bad4U;
1093   registers_[12] = 0x50Bad4U;
1094 }
1095
1096 // Some Operating Systems allow unaligned access on ARMv7 targets. We
1097 // assume that unaligned accesses are not allowed unless the v8 build system
1098 // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
1099 // The following statements below describes the behavior of the ARM CPUs
1100 // that don't support unaligned access.
1101 // Some ARM platforms raise an interrupt on detecting unaligned access.
1102 // On others it does a funky rotation thing.  For now we
1103 // simply disallow unaligned reads.  Note that simulator runs have the runtime
1104 // system running directly on the host system and only generated code is
1105 // executed in the simulator.  Since the host is typically IA32 we will not
1106 // get the correct ARM-like behaviour on unaligned accesses for those ARM
1107 // targets that don't support unaligned loads and stores.
1108
1109
1110 int Simulator::ReadW(int32_t addr, Instruction* instr) {
1111 #if V8_TARGET_CAN_READ_UNALIGNED
1112   intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1113   return *ptr;
1114 #else
1115   if ((addr & 3) == 0) {
1116     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1117     return *ptr;
1118   }
1119   PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1120          addr,
1121          reinterpret_cast<intptr_t>(instr));
1122   UNIMPLEMENTED();
1123   return 0;
1124 #endif
1125 }
1126
1127
1128 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
1129 #if V8_TARGET_CAN_READ_UNALIGNED
1130   intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1131   *ptr = value;
1132   return;
1133 #else
1134   if ((addr & 3) == 0) {
1135     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1136     *ptr = value;
1137     return;
1138   }
1139   PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1140          addr,
1141          reinterpret_cast<intptr_t>(instr));
1142   UNIMPLEMENTED();
1143 #endif
1144 }
1145
1146
1147 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
1148 #if V8_TARGET_CAN_READ_UNALIGNED
1149   uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1150   return *ptr;
1151 #else
1152   if ((addr & 1) == 0) {
1153     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1154     return *ptr;
1155   }
1156   PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1157          addr,
1158          reinterpret_cast<intptr_t>(instr));
1159   UNIMPLEMENTED();
1160   return 0;
1161 #endif
1162 }
1163
1164
1165 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
1166 #if V8_TARGET_CAN_READ_UNALIGNED
1167   int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1168   return *ptr;
1169 #else
1170   if ((addr & 1) == 0) {
1171     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1172     return *ptr;
1173   }
1174   PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
1175   UNIMPLEMENTED();
1176   return 0;
1177 #endif
1178 }
1179
1180
1181 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
1182 #if V8_TARGET_CAN_READ_UNALIGNED
1183   uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1184   *ptr = value;
1185   return;
1186 #else
1187   if ((addr & 1) == 0) {
1188     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1189     *ptr = value;
1190     return;
1191   }
1192   PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1193          addr,
1194          reinterpret_cast<intptr_t>(instr));
1195   UNIMPLEMENTED();
1196 #endif
1197 }
1198
1199
1200 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
1201 #if V8_TARGET_CAN_READ_UNALIGNED
1202   int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1203   *ptr = value;
1204   return;
1205 #else
1206   if ((addr & 1) == 0) {
1207     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1208     *ptr = value;
1209     return;
1210   }
1211   PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1212          addr,
1213          reinterpret_cast<intptr_t>(instr));
1214   UNIMPLEMENTED();
1215 #endif
1216 }
1217
1218
1219 uint8_t Simulator::ReadBU(int32_t addr) {
1220   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1221   return *ptr;
1222 }
1223
1224
1225 int8_t Simulator::ReadB(int32_t addr) {
1226   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1227   return *ptr;
1228 }
1229
1230
1231 void Simulator::WriteB(int32_t addr, uint8_t value) {
1232   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1233   *ptr = value;
1234 }
1235
1236
1237 void Simulator::WriteB(int32_t addr, int8_t value) {
1238   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1239   *ptr = value;
1240 }
1241
1242
1243 int32_t* Simulator::ReadDW(int32_t addr) {
1244 #if V8_TARGET_CAN_READ_UNALIGNED
1245   int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1246   return ptr;
1247 #else
1248   if ((addr & 3) == 0) {
1249     int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1250     return ptr;
1251   }
1252   PrintF("Unaligned read at 0x%08x\n", addr);
1253   UNIMPLEMENTED();
1254   return 0;
1255 #endif
1256 }
1257
1258
1259 void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) {
1260 #if V8_TARGET_CAN_READ_UNALIGNED
1261   int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1262   *ptr++ = value1;
1263   *ptr = value2;
1264   return;
1265 #else
1266   if ((addr & 3) == 0) {
1267     int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1268     *ptr++ = value1;
1269     *ptr = value2;
1270     return;
1271   }
1272   PrintF("Unaligned write at 0x%08x\n", addr);
1273   UNIMPLEMENTED();
1274 #endif
1275 }
1276
1277
1278 // Returns the limit of the stack area to enable checking for stack overflows.
1279 uintptr_t Simulator::StackLimit() const {
1280   // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
1281   // pushing values.
1282   return reinterpret_cast<uintptr_t>(stack_) + 1024;
1283 }
1284
1285
1286 // Unsupported instructions use Format to print an error and stop execution.
1287 void Simulator::Format(Instruction* instr, const char* format) {
1288   PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
1289          reinterpret_cast<intptr_t>(instr), format);
1290   UNIMPLEMENTED();
1291 }
1292
1293
1294 // Checks if the current instruction should be executed based on its
1295 // condition bits.
1296 bool Simulator::ConditionallyExecute(Instruction* instr) {
1297   switch (instr->ConditionField()) {
1298     case eq: return z_flag_;
1299     case ne: return !z_flag_;
1300     case cs: return c_flag_;
1301     case cc: return !c_flag_;
1302     case mi: return n_flag_;
1303     case pl: return !n_flag_;
1304     case vs: return v_flag_;
1305     case vc: return !v_flag_;
1306     case hi: return c_flag_ && !z_flag_;
1307     case ls: return !c_flag_ || z_flag_;
1308     case ge: return n_flag_ == v_flag_;
1309     case lt: return n_flag_ != v_flag_;
1310     case gt: return !z_flag_ && (n_flag_ == v_flag_);
1311     case le: return z_flag_ || (n_flag_ != v_flag_);
1312     case al: return true;
1313     default: UNREACHABLE();
1314   }
1315   return false;
1316 }
1317
1318
1319 // Calculate and set the Negative and Zero flags.
1320 void Simulator::SetNZFlags(int32_t val) {
1321   n_flag_ = (val < 0);
1322   z_flag_ = (val == 0);
1323 }
1324
1325
1326 // Set the Carry flag.
1327 void Simulator::SetCFlag(bool val) {
1328   c_flag_ = val;
1329 }
1330
1331
1332 // Set the oVerflow flag.
1333 void Simulator::SetVFlag(bool val) {
1334   v_flag_ = val;
1335 }
1336
1337
1338 // Calculate C flag value for additions.
1339 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
1340   uint32_t uleft = static_cast<uint32_t>(left);
1341   uint32_t uright = static_cast<uint32_t>(right);
1342   uint32_t urest  = 0xffffffffU - uleft;
1343
1344   return (uright > urest) ||
1345          (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
1346 }
1347
1348
1349 // Calculate C flag value for subtractions.
1350 bool Simulator::BorrowFrom(int32_t left, int32_t right) {
1351   uint32_t uleft = static_cast<uint32_t>(left);
1352   uint32_t uright = static_cast<uint32_t>(right);
1353
1354   return (uright > uleft);
1355 }
1356
1357
1358 // Calculate V flag value for additions and subtractions.
1359 bool Simulator::OverflowFrom(int32_t alu_out,
1360                              int32_t left, int32_t right, bool addition) {
1361   bool overflow;
1362   if (addition) {
1363                // operands have the same sign
1364     overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
1365                // and operands and result have different sign
1366                && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1367   } else {
1368                // operands have different signs
1369     overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
1370                // and first operand and result have different signs
1371                && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1372   }
1373   return overflow;
1374 }
1375
1376
1377 // Support for VFP comparisons.
1378 void Simulator::Compute_FPSCR_Flags(double val1, double val2) {
1379   if (isnan(val1) || isnan(val2)) {
1380     n_flag_FPSCR_ = false;
1381     z_flag_FPSCR_ = false;
1382     c_flag_FPSCR_ = true;
1383     v_flag_FPSCR_ = true;
1384   // All non-NaN cases.
1385   } else if (val1 == val2) {
1386     n_flag_FPSCR_ = false;
1387     z_flag_FPSCR_ = true;
1388     c_flag_FPSCR_ = true;
1389     v_flag_FPSCR_ = false;
1390   } else if (val1 < val2) {
1391     n_flag_FPSCR_ = true;
1392     z_flag_FPSCR_ = false;
1393     c_flag_FPSCR_ = false;
1394     v_flag_FPSCR_ = false;
1395   } else {
1396     // Case when (val1 > val2).
1397     n_flag_FPSCR_ = false;
1398     z_flag_FPSCR_ = false;
1399     c_flag_FPSCR_ = true;
1400     v_flag_FPSCR_ = false;
1401   }
1402 }
1403
1404
1405 void Simulator::Copy_FPSCR_to_APSR() {
1406   n_flag_ = n_flag_FPSCR_;
1407   z_flag_ = z_flag_FPSCR_;
1408   c_flag_ = c_flag_FPSCR_;
1409   v_flag_ = v_flag_FPSCR_;
1410 }
1411
1412
1413 // Addressing Mode 1 - Data-processing operands:
1414 // Get the value based on the shifter_operand with register.
1415 int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
1416   ShiftOp shift = instr->ShiftField();
1417   int shift_amount = instr->ShiftAmountValue();
1418   int32_t result = get_register(instr->RmValue());
1419   if (instr->Bit(4) == 0) {
1420     // by immediate
1421     if ((shift == ROR) && (shift_amount == 0)) {
1422       UNIMPLEMENTED();
1423       return result;
1424     } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
1425       shift_amount = 32;
1426     }
1427     switch (shift) {
1428       case ASR: {
1429         if (shift_amount == 0) {
1430           if (result < 0) {
1431             result = 0xffffffff;
1432             *carry_out = true;
1433           } else {
1434             result = 0;
1435             *carry_out = false;
1436           }
1437         } else {
1438           result >>= (shift_amount - 1);
1439           *carry_out = (result & 1) == 1;
1440           result >>= 1;
1441         }
1442         break;
1443       }
1444
1445       case LSL: {
1446         if (shift_amount == 0) {
1447           *carry_out = c_flag_;
1448         } else {
1449           result <<= (shift_amount - 1);
1450           *carry_out = (result < 0);
1451           result <<= 1;
1452         }
1453         break;
1454       }
1455
1456       case LSR: {
1457         if (shift_amount == 0) {
1458           result = 0;
1459           *carry_out = c_flag_;
1460         } else {
1461           uint32_t uresult = static_cast<uint32_t>(result);
1462           uresult >>= (shift_amount - 1);
1463           *carry_out = (uresult & 1) == 1;
1464           uresult >>= 1;
1465           result = static_cast<int32_t>(uresult);
1466         }
1467         break;
1468       }
1469
1470       case ROR: {
1471         UNIMPLEMENTED();
1472         break;
1473       }
1474
1475       default: {
1476         UNREACHABLE();
1477         break;
1478       }
1479     }
1480   } else {
1481     // by register
1482     int rs = instr->RsValue();
1483     shift_amount = get_register(rs) &0xff;
1484     switch (shift) {
1485       case ASR: {
1486         if (shift_amount == 0) {
1487           *carry_out = c_flag_;
1488         } else if (shift_amount < 32) {
1489           result >>= (shift_amount - 1);
1490           *carry_out = (result & 1) == 1;
1491           result >>= 1;
1492         } else {
1493           ASSERT(shift_amount >= 32);
1494           if (result < 0) {
1495             *carry_out = true;
1496             result = 0xffffffff;
1497           } else {
1498             *carry_out = false;
1499             result = 0;
1500           }
1501         }
1502         break;
1503       }
1504
1505       case LSL: {
1506         if (shift_amount == 0) {
1507           *carry_out = c_flag_;
1508         } else if (shift_amount < 32) {
1509           result <<= (shift_amount - 1);
1510           *carry_out = (result < 0);
1511           result <<= 1;
1512         } else if (shift_amount == 32) {
1513           *carry_out = (result & 1) == 1;
1514           result = 0;
1515         } else {
1516           ASSERT(shift_amount > 32);
1517           *carry_out = false;
1518           result = 0;
1519         }
1520         break;
1521       }
1522
1523       case LSR: {
1524         if (shift_amount == 0) {
1525           *carry_out = c_flag_;
1526         } else if (shift_amount < 32) {
1527           uint32_t uresult = static_cast<uint32_t>(result);
1528           uresult >>= (shift_amount - 1);
1529           *carry_out = (uresult & 1) == 1;
1530           uresult >>= 1;
1531           result = static_cast<int32_t>(uresult);
1532         } else if (shift_amount == 32) {
1533           *carry_out = (result < 0);
1534           result = 0;
1535         } else {
1536           *carry_out = false;
1537           result = 0;
1538         }
1539         break;
1540       }
1541
1542       case ROR: {
1543         UNIMPLEMENTED();
1544         break;
1545       }
1546
1547       default: {
1548         UNREACHABLE();
1549         break;
1550       }
1551     }
1552   }
1553   return result;
1554 }
1555
1556
1557 // Addressing Mode 1 - Data-processing operands:
1558 // Get the value based on the shifter_operand with immediate.
1559 int32_t Simulator::GetImm(Instruction* instr, bool* carry_out) {
1560   int rotate = instr->RotateValue() * 2;
1561   int immed8 = instr->Immed8Value();
1562   int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
1563   *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
1564   return imm;
1565 }
1566
1567
1568 static int count_bits(int bit_vector) {
1569   int count = 0;
1570   while (bit_vector != 0) {
1571     if ((bit_vector & 1) != 0) {
1572       count++;
1573     }
1574     bit_vector >>= 1;
1575   }
1576   return count;
1577 }
1578
1579
1580 void Simulator::ProcessPUW(Instruction* instr,
1581                            int num_regs,
1582                            int reg_size,
1583                            intptr_t* start_address,
1584                            intptr_t* end_address) {
1585   int rn = instr->RnValue();
1586   int32_t rn_val = get_register(rn);
1587   switch (instr->PUField()) {
1588     case da_x: {
1589       UNIMPLEMENTED();
1590       break;
1591     }
1592     case ia_x: {
1593       *start_address = rn_val;
1594       *end_address = rn_val + (num_regs * reg_size) - reg_size;
1595       rn_val = rn_val + (num_regs * reg_size);
1596       break;
1597     }
1598     case db_x: {
1599       *start_address = rn_val - (num_regs * reg_size);
1600       *end_address = rn_val - reg_size;
1601       rn_val = *start_address;
1602       break;
1603     }
1604     case ib_x: {
1605       *start_address = rn_val + reg_size;
1606       *end_address = rn_val + (num_regs * reg_size);
1607       rn_val = *end_address;
1608       break;
1609     }
1610     default: {
1611       UNREACHABLE();
1612       break;
1613     }
1614   }
1615   if (instr->HasW()) {
1616     set_register(rn, rn_val);
1617   }
1618 }
1619
1620 // Addressing Mode 4 - Load and Store Multiple
1621 void Simulator::HandleRList(Instruction* instr, bool load) {
1622   int rlist = instr->RlistValue();
1623   int num_regs = count_bits(rlist);
1624
1625   intptr_t start_address = 0;
1626   intptr_t end_address = 0;
1627   ProcessPUW(instr, num_regs, kPointerSize, &start_address, &end_address);
1628
1629   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
1630   // Catch null pointers a little earlier.
1631   ASSERT(start_address > 8191 || start_address < 0);
1632   int reg = 0;
1633   while (rlist != 0) {
1634     if ((rlist & 1) != 0) {
1635       if (load) {
1636         set_register(reg, *address);
1637       } else {
1638         *address = get_register(reg);
1639       }
1640       address += 1;
1641     }
1642     reg++;
1643     rlist >>= 1;
1644   }
1645   ASSERT(end_address == ((intptr_t)address) - 4);
1646 }
1647
1648
1649 // Addressing Mode 6 - Load and Store Multiple Coprocessor registers.
1650 void Simulator::HandleVList(Instruction* instr) {
1651   VFPRegPrecision precision =
1652       (instr->SzValue() == 0) ? kSinglePrecision : kDoublePrecision;
1653   int operand_size = (precision == kSinglePrecision) ? 4 : 8;
1654
1655   bool load = (instr->VLValue() == 0x1);
1656
1657   int vd;
1658   int num_regs;
1659   vd = instr->VFPDRegValue(precision);
1660   if (precision == kSinglePrecision) {
1661     num_regs = instr->Immed8Value();
1662   } else {
1663     num_regs = instr->Immed8Value() / 2;
1664   }
1665
1666   intptr_t start_address = 0;
1667   intptr_t end_address = 0;
1668   ProcessPUW(instr, num_regs, operand_size, &start_address, &end_address);
1669
1670   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
1671   for (int reg = vd; reg < vd + num_regs; reg++) {
1672     if (precision == kSinglePrecision) {
1673       if (load) {
1674         set_s_register_from_sinteger(
1675             reg, ReadW(reinterpret_cast<int32_t>(address), instr));
1676       } else {
1677         WriteW(reinterpret_cast<int32_t>(address),
1678                get_sinteger_from_s_register(reg), instr);
1679       }
1680       address += 1;
1681     } else {
1682       if (load) {
1683         set_s_register_from_sinteger(
1684             2 * reg, ReadW(reinterpret_cast<int32_t>(address), instr));
1685         set_s_register_from_sinteger(
1686             2 * reg + 1, ReadW(reinterpret_cast<int32_t>(address + 1), instr));
1687       } else {
1688         WriteW(reinterpret_cast<int32_t>(address),
1689                get_sinteger_from_s_register(2 * reg), instr);
1690         WriteW(reinterpret_cast<int32_t>(address + 1),
1691                get_sinteger_from_s_register(2 * reg + 1), instr);
1692       }
1693       address += 2;
1694     }
1695   }
1696   ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address);
1697 }
1698
1699
1700 // Calls into the V8 runtime are based on this very simple interface.
1701 // Note: To be able to return two values from some calls the code in runtime.cc
1702 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
1703 // 64-bit value. With the code below we assume that all runtime calls return
1704 // 64 bits of result. If they don't, the r1 result register contains a bogus
1705 // value, which is fine because it is caller-saved.
1706 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1707                                         int32_t arg1,
1708                                         int32_t arg2,
1709                                         int32_t arg3,
1710                                         int32_t arg4,
1711                                         int32_t arg5);
1712 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
1713                                          int32_t arg1,
1714                                          int32_t arg2,
1715                                          int32_t arg3);
1716
1717 // This signature supports direct call in to API function native callback
1718 // (refer to InvocationCallback in v8.h).
1719 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
1720
1721 // This signature supports direct call to accessor getter callback.
1722 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
1723                                                                   int32_t arg1);
1724
1725 // Software interrupt instructions are used by the simulator to call into the
1726 // C-based V8 runtime.
1727 void Simulator::SoftwareInterrupt(Instruction* instr) {
1728   int svc = instr->SvcValue();
1729   switch (svc) {
1730     case kCallRtRedirected: {
1731       // Check if stack is aligned. Error if not aligned is reported below to
1732       // include information on the function called.
1733       bool stack_aligned =
1734           (get_register(sp)
1735            & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;
1736       Redirection* redirection = Redirection::FromSwiInstruction(instr);
1737       int32_t arg0 = get_register(r0);
1738       int32_t arg1 = get_register(r1);
1739       int32_t arg2 = get_register(r2);
1740       int32_t arg3 = get_register(r3);
1741       int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1742       int32_t arg4 = stack_pointer[0];
1743       int32_t arg5 = stack_pointer[1];
1744       bool fp_call =
1745          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1746          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1747          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1748          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1749       if (use_eabi_hardfloat()) {
1750         // With the hard floating point calling convention, double
1751         // arguments are passed in VFP registers. Fetch the arguments
1752         // from there and call the builtin using soft floating point
1753         // convention.
1754         switch (redirection->type()) {
1755         case ExternalReference::BUILTIN_FP_FP_CALL:
1756         case ExternalReference::BUILTIN_COMPARE_CALL:
1757           arg0 = vfp_register[0];
1758           arg1 = vfp_register[1];
1759           arg2 = vfp_register[2];
1760           arg3 = vfp_register[3];
1761           break;
1762         case ExternalReference::BUILTIN_FP_CALL:
1763           arg0 = vfp_register[0];
1764           arg1 = vfp_register[1];
1765           break;
1766         case ExternalReference::BUILTIN_FP_INT_CALL:
1767           arg0 = vfp_register[0];
1768           arg1 = vfp_register[1];
1769           arg2 = get_register(0);
1770           break;
1771         default:
1772           break;
1773         }
1774       }
1775       // This is dodgy but it works because the C entry stubs are never moved.
1776       // See comment in codegen-arm.cc and bug 1242173.
1777       int32_t saved_lr = get_register(lr);
1778       intptr_t external =
1779           reinterpret_cast<intptr_t>(redirection->external_function());
1780       if (fp_call) {
1781         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1782           SimulatorRuntimeFPCall target =
1783               reinterpret_cast<SimulatorRuntimeFPCall>(external);
1784           double dval0, dval1;
1785           int32_t ival;
1786           switch (redirection->type()) {
1787           case ExternalReference::BUILTIN_FP_FP_CALL:
1788           case ExternalReference::BUILTIN_COMPARE_CALL:
1789             GetFpArgs(&dval0, &dval1);
1790             PrintF("Call to host function at %p with args %f, %f",
1791                 FUNCTION_ADDR(target), dval0, dval1);
1792             break;
1793           case ExternalReference::BUILTIN_FP_CALL:
1794             GetFpArgs(&dval0);
1795             PrintF("Call to host function at %p with arg %f",
1796                 FUNCTION_ADDR(target), dval0);
1797             break;
1798           case ExternalReference::BUILTIN_FP_INT_CALL:
1799             GetFpArgs(&dval0, &ival);
1800             PrintF("Call to host function at %p with args %f, %d",
1801                 FUNCTION_ADDR(target), dval0, ival);
1802             break;
1803           default:
1804             UNREACHABLE();
1805             break;
1806           }
1807           if (!stack_aligned) {
1808             PrintF(" with unaligned stack %08x\n", get_register(sp));
1809           }
1810           PrintF("\n");
1811         }
1812         CHECK(stack_aligned);
1813         if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) {
1814           SimulatorRuntimeFPCall target =
1815               reinterpret_cast<SimulatorRuntimeFPCall>(external);
1816           double result = target(arg0, arg1, arg2, arg3);
1817           SetFpResult(result);
1818         } else {
1819           SimulatorRuntimeCall target =
1820               reinterpret_cast<SimulatorRuntimeCall>(external);
1821           int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
1822           int32_t lo_res = static_cast<int32_t>(result);
1823           int32_t hi_res = static_cast<int32_t>(result >> 32);
1824           if (::v8::internal::FLAG_trace_sim) {
1825             PrintF("Returned %08x\n", lo_res);
1826           }
1827           set_register(r0, lo_res);
1828           set_register(r1, hi_res);
1829         }
1830       } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1831         SimulatorRuntimeDirectApiCall target =
1832             reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
1833         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1834           PrintF("Call to host function at %p args %08x",
1835               FUNCTION_ADDR(target), arg0);
1836           if (!stack_aligned) {
1837             PrintF(" with unaligned stack %08x\n", get_register(sp));
1838           }
1839           PrintF("\n");
1840         }
1841         CHECK(stack_aligned);
1842         v8::Handle<v8::Value> result = target(arg0);
1843         if (::v8::internal::FLAG_trace_sim) {
1844           PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
1845         }
1846         set_register(r0, (int32_t) *result);
1847       } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
1848         SimulatorRuntimeDirectGetterCall target =
1849             reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
1850         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1851           PrintF("Call to host function at %p args %08x %08x",
1852               FUNCTION_ADDR(target), arg0, arg1);
1853           if (!stack_aligned) {
1854             PrintF(" with unaligned stack %08x\n", get_register(sp));
1855           }
1856           PrintF("\n");
1857         }
1858         CHECK(stack_aligned);
1859         v8::Handle<v8::Value> result = target(arg0, arg1);
1860         if (::v8::internal::FLAG_trace_sim) {
1861           PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
1862         }
1863         set_register(r0, (int32_t) *result);
1864       } else {
1865         // builtin call.
1866         ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
1867         SimulatorRuntimeCall target =
1868             reinterpret_cast<SimulatorRuntimeCall>(external);
1869         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1870           PrintF(
1871               "Call to host function at %p"
1872               "args %08x, %08x, %08x, %08x, %08x, %08x",
1873               FUNCTION_ADDR(target),
1874               arg0,
1875               arg1,
1876               arg2,
1877               arg3,
1878               arg4,
1879               arg5);
1880           if (!stack_aligned) {
1881             PrintF(" with unaligned stack %08x\n", get_register(sp));
1882           }
1883           PrintF("\n");
1884         }
1885         CHECK(stack_aligned);
1886         int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
1887         int32_t lo_res = static_cast<int32_t>(result);
1888         int32_t hi_res = static_cast<int32_t>(result >> 32);
1889         if (::v8::internal::FLAG_trace_sim) {
1890           PrintF("Returned %08x\n", lo_res);
1891         }
1892         set_register(r0, lo_res);
1893         set_register(r1, hi_res);
1894       }
1895       set_register(lr, saved_lr);
1896       set_pc(get_register(lr));
1897       break;
1898     }
1899     case kBreakpoint: {
1900       ArmDebugger dbg(this);
1901       dbg.Debug();
1902       break;
1903     }
1904     // stop uses all codes greater than 1 << 23.
1905     default: {
1906       if (svc >= (1 << 23)) {
1907         uint32_t code = svc & kStopCodeMask;
1908         if (isWatchedStop(code)) {
1909           IncreaseStopCounter(code);
1910         }
1911         // Stop if it is enabled, otherwise go on jumping over the stop
1912         // and the message address.
1913         if (isEnabledStop(code)) {
1914           ArmDebugger dbg(this);
1915           dbg.Stop(instr);
1916         } else {
1917           set_pc(get_pc() + 2 * Instruction::kInstrSize);
1918         }
1919       } else {
1920         // This is not a valid svc code.
1921         UNREACHABLE();
1922         break;
1923       }
1924     }
1925   }
1926 }
1927
1928
1929 // Stop helper functions.
1930 bool Simulator::isStopInstruction(Instruction* instr) {
1931   return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
1932 }
1933
1934
1935 bool Simulator::isWatchedStop(uint32_t code) {
1936   ASSERT(code <= kMaxStopCode);
1937   return code < kNumOfWatchedStops;
1938 }
1939
1940
1941 bool Simulator::isEnabledStop(uint32_t code) {
1942   ASSERT(code <= kMaxStopCode);
1943   // Unwatched stops are always enabled.
1944   return !isWatchedStop(code) ||
1945     !(watched_stops[code].count & kStopDisabledBit);
1946 }
1947
1948
1949 void Simulator::EnableStop(uint32_t code) {
1950   ASSERT(isWatchedStop(code));
1951   if (!isEnabledStop(code)) {
1952     watched_stops[code].count &= ~kStopDisabledBit;
1953   }
1954 }
1955
1956
1957 void Simulator::DisableStop(uint32_t code) {
1958   ASSERT(isWatchedStop(code));
1959   if (isEnabledStop(code)) {
1960     watched_stops[code].count |= kStopDisabledBit;
1961   }
1962 }
1963
1964
1965 void Simulator::IncreaseStopCounter(uint32_t code) {
1966   ASSERT(code <= kMaxStopCode);
1967   ASSERT(isWatchedStop(code));
1968   if ((watched_stops[code].count & ~(1 << 31)) == 0x7fffffff) {
1969     PrintF("Stop counter for code %i has overflowed.\n"
1970            "Enabling this code and reseting the counter to 0.\n", code);
1971     watched_stops[code].count = 0;
1972     EnableStop(code);
1973   } else {
1974     watched_stops[code].count++;
1975   }
1976 }
1977
1978
1979 // Print a stop status.
1980 void Simulator::PrintStopInfo(uint32_t code) {
1981   ASSERT(code <= kMaxStopCode);
1982   if (!isWatchedStop(code)) {
1983     PrintF("Stop not watched.");
1984   } else {
1985     const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
1986     int32_t count = watched_stops[code].count & ~kStopDisabledBit;
1987     // Don't print the state of unused breakpoints.
1988     if (count != 0) {
1989       if (watched_stops[code].desc) {
1990         PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
1991                code, code, state, count, watched_stops[code].desc);
1992       } else {
1993         PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
1994                code, code, state, count);
1995       }
1996     }
1997   }
1998 }
1999
2000
2001 // Handle execution based on instruction types.
2002
2003 // Instruction types 0 and 1 are both rolled into one function because they
2004 // only differ in the handling of the shifter_operand.
2005 void Simulator::DecodeType01(Instruction* instr) {
2006   int type = instr->TypeValue();
2007   if ((type == 0) && instr->IsSpecialType0()) {
2008     // multiply instruction or extra loads and stores
2009     if (instr->Bits(7, 4) == 9) {
2010       if (instr->Bit(24) == 0) {
2011         // Raw field decoding here. Multiply instructions have their Rd in
2012         // funny places.
2013         int rn = instr->RnValue();
2014         int rm = instr->RmValue();
2015         int rs = instr->RsValue();
2016         int32_t rs_val = get_register(rs);
2017         int32_t rm_val = get_register(rm);
2018         if (instr->Bit(23) == 0) {
2019           if (instr->Bit(21) == 0) {
2020             // The MUL instruction description (A 4.1.33) refers to Rd as being
2021             // the destination for the operation, but it confusingly uses the
2022             // Rn field to encode it.
2023             // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
2024             int rd = rn;  // Remap the rn field to the Rd register.
2025             int32_t alu_out = rm_val * rs_val;
2026             set_register(rd, alu_out);
2027             if (instr->HasS()) {
2028               SetNZFlags(alu_out);
2029             }
2030           } else {
2031             // The MLA instruction description (A 4.1.28) refers to the order
2032             // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
2033             // Rn field to encode the Rd register and the Rd field to encode
2034             // the Rn register.
2035             Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
2036           }
2037         } else {
2038           // The signed/long multiply instructions use the terms RdHi and RdLo
2039           // when referring to the target registers. They are mapped to the Rn
2040           // and Rd fields as follows:
2041           // RdLo == Rd
2042           // RdHi == Rn (This is confusingly stored in variable rd here
2043           //             because the mul instruction from above uses the
2044           //             Rn field to encode the Rd register. Good luck figuring
2045           //             this out without reading the ARM instruction manual
2046           //             at a very detailed level.)
2047           // Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm");
2048           int rd_hi = rn;  // Remap the rn field to the RdHi register.
2049           int rd_lo = instr->RdValue();
2050           int32_t hi_res = 0;
2051           int32_t lo_res = 0;
2052           if (instr->Bit(22) == 1) {
2053             int64_t left_op  = static_cast<int32_t>(rm_val);
2054             int64_t right_op = static_cast<int32_t>(rs_val);
2055             uint64_t result = left_op * right_op;
2056             hi_res = static_cast<int32_t>(result >> 32);
2057             lo_res = static_cast<int32_t>(result & 0xffffffff);
2058           } else {
2059             // unsigned multiply
2060             uint64_t left_op  = static_cast<uint32_t>(rm_val);
2061             uint64_t right_op = static_cast<uint32_t>(rs_val);
2062             uint64_t result = left_op * right_op;
2063             hi_res = static_cast<int32_t>(result >> 32);
2064             lo_res = static_cast<int32_t>(result & 0xffffffff);
2065           }
2066           set_register(rd_lo, lo_res);
2067           set_register(rd_hi, hi_res);
2068           if (instr->HasS()) {
2069             UNIMPLEMENTED();
2070           }
2071         }
2072       } else {
2073         UNIMPLEMENTED();  // Not used by V8.
2074       }
2075     } else {
2076       // extra load/store instructions
2077       int rd = instr->RdValue();
2078       int rn = instr->RnValue();
2079       int32_t rn_val = get_register(rn);
2080       int32_t addr = 0;
2081       if (instr->Bit(22) == 0) {
2082         int rm = instr->RmValue();
2083         int32_t rm_val = get_register(rm);
2084         switch (instr->PUField()) {
2085           case da_x: {
2086             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
2087             ASSERT(!instr->HasW());
2088             addr = rn_val;
2089             rn_val -= rm_val;
2090             set_register(rn, rn_val);
2091             break;
2092           }
2093           case ia_x: {
2094             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
2095             ASSERT(!instr->HasW());
2096             addr = rn_val;
2097             rn_val += rm_val;
2098             set_register(rn, rn_val);
2099             break;
2100           }
2101           case db_x: {
2102             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
2103             rn_val -= rm_val;
2104             addr = rn_val;
2105             if (instr->HasW()) {
2106               set_register(rn, rn_val);
2107             }
2108             break;
2109           }
2110           case ib_x: {
2111             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
2112             rn_val += rm_val;
2113             addr = rn_val;
2114             if (instr->HasW()) {
2115               set_register(rn, rn_val);
2116             }
2117             break;
2118           }
2119           default: {
2120             // The PU field is a 2-bit field.
2121             UNREACHABLE();
2122             break;
2123           }
2124         }
2125       } else {
2126         int32_t imm_val = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
2127         switch (instr->PUField()) {
2128           case da_x: {
2129             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
2130             ASSERT(!instr->HasW());
2131             addr = rn_val;
2132             rn_val -= imm_val;
2133             set_register(rn, rn_val);
2134             break;
2135           }
2136           case ia_x: {
2137             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
2138             ASSERT(!instr->HasW());
2139             addr = rn_val;
2140             rn_val += imm_val;
2141             set_register(rn, rn_val);
2142             break;
2143           }
2144           case db_x: {
2145             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
2146             rn_val -= imm_val;
2147             addr = rn_val;
2148             if (instr->HasW()) {
2149               set_register(rn, rn_val);
2150             }
2151             break;
2152           }
2153           case ib_x: {
2154             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
2155             rn_val += imm_val;
2156             addr = rn_val;
2157             if (instr->HasW()) {
2158               set_register(rn, rn_val);
2159             }
2160             break;
2161           }
2162           default: {
2163             // The PU field is a 2-bit field.
2164             UNREACHABLE();
2165             break;
2166           }
2167         }
2168       }
2169       if (((instr->Bits(7, 4) & 0xd) == 0xd) && (instr->Bit(20) == 0)) {
2170         ASSERT((rd % 2) == 0);
2171         if (instr->HasH()) {
2172           // The strd instruction.
2173           int32_t value1 = get_register(rd);
2174           int32_t value2 = get_register(rd+1);
2175           WriteDW(addr, value1, value2);
2176         } else {
2177           // The ldrd instruction.
2178           int* rn_data = ReadDW(addr);
2179           set_dw_register(rd, rn_data);
2180         }
2181       } else if (instr->HasH()) {
2182         if (instr->HasSign()) {
2183           if (instr->HasL()) {
2184             int16_t val = ReadH(addr, instr);
2185             set_register(rd, val);
2186           } else {
2187             int16_t val = get_register(rd);
2188             WriteH(addr, val, instr);
2189           }
2190         } else {
2191           if (instr->HasL()) {
2192             uint16_t val = ReadHU(addr, instr);
2193             set_register(rd, val);
2194           } else {
2195             uint16_t val = get_register(rd);
2196             WriteH(addr, val, instr);
2197           }
2198         }
2199       } else {
2200         // signed byte loads
2201         ASSERT(instr->HasSign());
2202         ASSERT(instr->HasL());
2203         int8_t val = ReadB(addr);
2204         set_register(rd, val);
2205       }
2206       return;
2207     }
2208   } else if ((type == 0) && instr->IsMiscType0()) {
2209     if (instr->Bits(22, 21) == 1) {
2210       int rm = instr->RmValue();
2211       switch (instr->BitField(7, 4)) {
2212         case BX:
2213           set_pc(get_register(rm));
2214           break;
2215         case BLX: {
2216           uint32_t old_pc = get_pc();
2217           set_pc(get_register(rm));
2218           set_register(lr, old_pc + Instruction::kInstrSize);
2219           break;
2220         }
2221         case BKPT: {
2222           ArmDebugger dbg(this);
2223           PrintF("Simulator hit BKPT.\n");
2224           dbg.Debug();
2225           break;
2226         }
2227         default:
2228           UNIMPLEMENTED();
2229       }
2230     } else if (instr->Bits(22, 21) == 3) {
2231       int rm = instr->RmValue();
2232       int rd = instr->RdValue();
2233       switch (instr->BitField(7, 4)) {
2234         case CLZ: {
2235           uint32_t bits = get_register(rm);
2236           int leading_zeros = 0;
2237           if (bits == 0) {
2238             leading_zeros = 32;
2239           } else {
2240             while ((bits & 0x80000000u) == 0) {
2241               bits <<= 1;
2242               leading_zeros++;
2243             }
2244           }
2245           set_register(rd, leading_zeros);
2246           break;
2247         }
2248         default:
2249           UNIMPLEMENTED();
2250       }
2251     } else {
2252       PrintF("%08x\n", instr->InstructionBits());
2253       UNIMPLEMENTED();
2254     }
2255   } else {
2256     int rd = instr->RdValue();
2257     int rn = instr->RnValue();
2258     int32_t rn_val = get_register(rn);
2259     int32_t shifter_operand = 0;
2260     bool shifter_carry_out = 0;
2261     if (type == 0) {
2262       shifter_operand = GetShiftRm(instr, &shifter_carry_out);
2263     } else {
2264       ASSERT(instr->TypeValue() == 1);
2265       shifter_operand = GetImm(instr, &shifter_carry_out);
2266     }
2267     int32_t alu_out;
2268
2269     switch (instr->OpcodeField()) {
2270       case AND: {
2271         // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
2272         // Format(instr, "and'cond's 'rd, 'rn, 'imm");
2273         alu_out = rn_val & shifter_operand;
2274         set_register(rd, alu_out);
2275         if (instr->HasS()) {
2276           SetNZFlags(alu_out);
2277           SetCFlag(shifter_carry_out);
2278         }
2279         break;
2280       }
2281
2282       case EOR: {
2283         // Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");
2284         // Format(instr, "eor'cond's 'rd, 'rn, 'imm");
2285         alu_out = rn_val ^ shifter_operand;
2286         set_register(rd, alu_out);
2287         if (instr->HasS()) {
2288           SetNZFlags(alu_out);
2289           SetCFlag(shifter_carry_out);
2290         }
2291         break;
2292       }
2293
2294       case SUB: {
2295         // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");
2296         // Format(instr, "sub'cond's 'rd, 'rn, 'imm");
2297         alu_out = rn_val - shifter_operand;
2298         set_register(rd, alu_out);
2299         if (instr->HasS()) {
2300           SetNZFlags(alu_out);
2301           SetCFlag(!BorrowFrom(rn_val, shifter_operand));
2302           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
2303         }
2304         break;
2305       }
2306
2307       case RSB: {
2308         // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");
2309         // Format(instr, "rsb'cond's 'rd, 'rn, 'imm");
2310         alu_out = shifter_operand - rn_val;
2311         set_register(rd, alu_out);
2312         if (instr->HasS()) {
2313           SetNZFlags(alu_out);
2314           SetCFlag(!BorrowFrom(shifter_operand, rn_val));
2315           SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
2316         }
2317         break;
2318       }
2319
2320       case ADD: {
2321         // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");
2322         // Format(instr, "add'cond's 'rd, 'rn, 'imm");
2323         alu_out = rn_val + shifter_operand;
2324         set_register(rd, alu_out);
2325         if (instr->HasS()) {
2326           SetNZFlags(alu_out);
2327           SetCFlag(CarryFrom(rn_val, shifter_operand));
2328           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
2329         }
2330         break;
2331       }
2332
2333       case ADC: {
2334         // Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
2335         // Format(instr, "adc'cond's 'rd, 'rn, 'imm");
2336         alu_out = rn_val + shifter_operand + GetCarry();
2337         set_register(rd, alu_out);
2338         if (instr->HasS()) {
2339           SetNZFlags(alu_out);
2340           SetCFlag(CarryFrom(rn_val, shifter_operand, GetCarry()));
2341           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
2342         }
2343         break;
2344       }
2345
2346       case SBC: {
2347         Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
2348         Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
2349         break;
2350       }
2351
2352       case RSC: {
2353         Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
2354         Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
2355         break;
2356       }
2357
2358       case TST: {
2359         if (instr->HasS()) {
2360           // Format(instr, "tst'cond 'rn, 'shift_rm");
2361           // Format(instr, "tst'cond 'rn, 'imm");
2362           alu_out = rn_val & shifter_operand;
2363           SetNZFlags(alu_out);
2364           SetCFlag(shifter_carry_out);
2365         } else {
2366           // Format(instr, "movw'cond 'rd, 'imm").
2367           alu_out = instr->ImmedMovwMovtValue();
2368           set_register(rd, alu_out);
2369         }
2370         break;
2371       }
2372
2373       case TEQ: {
2374         if (instr->HasS()) {
2375           // Format(instr, "teq'cond 'rn, 'shift_rm");
2376           // Format(instr, "teq'cond 'rn, 'imm");
2377           alu_out = rn_val ^ shifter_operand;
2378           SetNZFlags(alu_out);
2379           SetCFlag(shifter_carry_out);
2380         } else {
2381           // Other instructions matching this pattern are handled in the
2382           // miscellaneous instructions part above.
2383           UNREACHABLE();
2384         }
2385         break;
2386       }
2387
2388       case CMP: {
2389         if (instr->HasS()) {
2390           // Format(instr, "cmp'cond 'rn, 'shift_rm");
2391           // Format(instr, "cmp'cond 'rn, 'imm");
2392           alu_out = rn_val - shifter_operand;
2393           SetNZFlags(alu_out);
2394           SetCFlag(!BorrowFrom(rn_val, shifter_operand));
2395           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
2396         } else {
2397           // Format(instr, "movt'cond 'rd, 'imm").
2398           alu_out = (get_register(rd) & 0xffff) |
2399               (instr->ImmedMovwMovtValue() << 16);
2400           set_register(rd, alu_out);
2401         }
2402         break;
2403       }
2404
2405       case CMN: {
2406         if (instr->HasS()) {
2407           // Format(instr, "cmn'cond 'rn, 'shift_rm");
2408           // Format(instr, "cmn'cond 'rn, 'imm");
2409           alu_out = rn_val + shifter_operand;
2410           SetNZFlags(alu_out);
2411           SetCFlag(!CarryFrom(rn_val, shifter_operand));
2412           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
2413         } else {
2414           // Other instructions matching this pattern are handled in the
2415           // miscellaneous instructions part above.
2416           UNREACHABLE();
2417         }
2418         break;
2419       }
2420
2421       case ORR: {
2422         // Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");
2423         // Format(instr, "orr'cond's 'rd, 'rn, 'imm");
2424         alu_out = rn_val | shifter_operand;
2425         set_register(rd, alu_out);
2426         if (instr->HasS()) {
2427           SetNZFlags(alu_out);
2428           SetCFlag(shifter_carry_out);
2429         }
2430         break;
2431       }
2432
2433       case MOV: {
2434         // Format(instr, "mov'cond's 'rd, 'shift_rm");
2435         // Format(instr, "mov'cond's 'rd, 'imm");
2436         alu_out = shifter_operand;
2437         set_register(rd, alu_out);
2438         if (instr->HasS()) {
2439           SetNZFlags(alu_out);
2440           SetCFlag(shifter_carry_out);
2441         }
2442         break;
2443       }
2444
2445       case BIC: {
2446         // Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");
2447         // Format(instr, "bic'cond's 'rd, 'rn, 'imm");
2448         alu_out = rn_val & ~shifter_operand;
2449         set_register(rd, alu_out);
2450         if (instr->HasS()) {
2451           SetNZFlags(alu_out);
2452           SetCFlag(shifter_carry_out);
2453         }
2454         break;
2455       }
2456
2457       case MVN: {
2458         // Format(instr, "mvn'cond's 'rd, 'shift_rm");
2459         // Format(instr, "mvn'cond's 'rd, 'imm");
2460         alu_out = ~shifter_operand;
2461         set_register(rd, alu_out);
2462         if (instr->HasS()) {
2463           SetNZFlags(alu_out);
2464           SetCFlag(shifter_carry_out);
2465         }
2466         break;
2467       }
2468
2469       default: {
2470         UNREACHABLE();
2471         break;
2472       }
2473     }
2474   }
2475 }
2476
2477
2478 void Simulator::DecodeType2(Instruction* instr) {
2479   int rd = instr->RdValue();
2480   int rn = instr->RnValue();
2481   int32_t rn_val = get_register(rn);
2482   int32_t im_val = instr->Offset12Value();
2483   int32_t addr = 0;
2484   switch (instr->PUField()) {
2485     case da_x: {
2486       // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
2487       ASSERT(!instr->HasW());
2488       addr = rn_val;
2489       rn_val -= im_val;
2490       set_register(rn, rn_val);
2491       break;
2492     }
2493     case ia_x: {
2494       // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
2495       ASSERT(!instr->HasW());
2496       addr = rn_val;
2497       rn_val += im_val;
2498       set_register(rn, rn_val);
2499       break;
2500     }
2501     case db_x: {
2502       // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
2503       rn_val -= im_val;
2504       addr = rn_val;
2505       if (instr->HasW()) {
2506         set_register(rn, rn_val);
2507       }
2508       break;
2509     }
2510     case ib_x: {
2511       // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
2512       rn_val += im_val;
2513       addr = rn_val;
2514       if (instr->HasW()) {
2515         set_register(rn, rn_val);
2516       }
2517       break;
2518     }
2519     default: {
2520       UNREACHABLE();
2521       break;
2522     }
2523   }
2524   if (instr->HasB()) {
2525     if (instr->HasL()) {
2526       byte val = ReadBU(addr);
2527       set_register(rd, val);
2528     } else {
2529       byte val = get_register(rd);
2530       WriteB(addr, val);
2531     }
2532   } else {
2533     if (instr->HasL()) {
2534       set_register(rd, ReadW(addr, instr));
2535     } else {
2536       WriteW(addr, get_register(rd), instr);
2537     }
2538   }
2539 }
2540
2541
2542 void Simulator::DecodeType3(Instruction* instr) {
2543   int rd = instr->RdValue();
2544   int rn = instr->RnValue();
2545   int32_t rn_val = get_register(rn);
2546   bool shifter_carry_out = 0;
2547   int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
2548   int32_t addr = 0;
2549   switch (instr->PUField()) {
2550     case da_x: {
2551       ASSERT(!instr->HasW());
2552       Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
2553       UNIMPLEMENTED();
2554       break;
2555     }
2556     case ia_x: {
2557       if (instr->HasW()) {
2558         ASSERT(instr->Bits(5, 4) == 0x1);
2559
2560         if (instr->Bit(22) == 0x1) {  // USAT.
2561           int32_t sat_pos = instr->Bits(20, 16);
2562           int32_t sat_val = (1 << sat_pos) - 1;
2563           int32_t shift = instr->Bits(11, 7);
2564           int32_t shift_type = instr->Bit(6);
2565           int32_t rm_val = get_register(instr->RmValue());
2566           if (shift_type == 0) {  // LSL
2567             rm_val <<= shift;
2568           } else {  // ASR
2569             rm_val >>= shift;
2570           }
2571           // If saturation occurs, the Q flag should be set in the CPSR.
2572           // There is no Q flag yet, and no instruction (MRS) to read the
2573           // CPSR directly.
2574           if (rm_val > sat_val) {
2575             rm_val = sat_val;
2576           } else if (rm_val < 0) {
2577             rm_val = 0;
2578           }
2579           set_register(rd, rm_val);
2580         } else {  // SSAT.
2581           UNIMPLEMENTED();
2582         }
2583         return;
2584       } else {
2585         Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
2586         UNIMPLEMENTED();
2587       }
2588       break;
2589     }
2590     case db_x: {
2591       // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
2592       addr = rn_val - shifter_operand;
2593       if (instr->HasW()) {
2594         set_register(rn, addr);
2595       }
2596       break;
2597     }
2598     case ib_x: {
2599       if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
2600         uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
2601         uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
2602         uint32_t msbit = widthminus1 + lsbit;
2603         if (msbit <= 31) {
2604           if (instr->Bit(22)) {
2605             // ubfx - unsigned bitfield extract.
2606             uint32_t rm_val =
2607                 static_cast<uint32_t>(get_register(instr->RmValue()));
2608             uint32_t extr_val = rm_val << (31 - msbit);
2609             extr_val = extr_val >> (31 - widthminus1);
2610             set_register(instr->RdValue(), extr_val);
2611           } else {
2612             // sbfx - signed bitfield extract.
2613             int32_t rm_val = get_register(instr->RmValue());
2614             int32_t extr_val = rm_val << (31 - msbit);
2615             extr_val = extr_val >> (31 - widthminus1);
2616             set_register(instr->RdValue(), extr_val);
2617           }
2618         } else {
2619           UNREACHABLE();
2620         }
2621         return;
2622       } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
2623         uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
2624         uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
2625         if (msbit >= lsbit) {
2626           // bfc or bfi - bitfield clear/insert.
2627           uint32_t rd_val =
2628               static_cast<uint32_t>(get_register(instr->RdValue()));
2629           uint32_t bitcount = msbit - lsbit + 1;
2630           uint32_t mask = (1 << bitcount) - 1;
2631           rd_val &= ~(mask << lsbit);
2632           if (instr->RmValue() != 15) {
2633             // bfi - bitfield insert.
2634             uint32_t rm_val =
2635                 static_cast<uint32_t>(get_register(instr->RmValue()));
2636             rm_val &= mask;
2637             rd_val |= rm_val << lsbit;
2638           }
2639           set_register(instr->RdValue(), rd_val);
2640         } else {
2641           UNREACHABLE();
2642         }
2643         return;
2644       } else {
2645         // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
2646         addr = rn_val + shifter_operand;
2647         if (instr->HasW()) {
2648           set_register(rn, addr);
2649         }
2650       }
2651       break;
2652     }
2653     default: {
2654       UNREACHABLE();
2655       break;
2656     }
2657   }
2658   if (instr->HasB()) {
2659     if (instr->HasL()) {
2660       uint8_t byte = ReadB(addr);
2661       set_register(rd, byte);
2662     } else {
2663       uint8_t byte = get_register(rd);
2664       WriteB(addr, byte);
2665     }
2666   } else {
2667     if (instr->HasL()) {
2668       set_register(rd, ReadW(addr, instr));
2669     } else {
2670       WriteW(addr, get_register(rd), instr);
2671     }
2672   }
2673 }
2674
2675
2676 void Simulator::DecodeType4(Instruction* instr) {
2677   ASSERT(instr->Bit(22) == 0);  // only allowed to be set in privileged mode
2678   if (instr->HasL()) {
2679     // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
2680     HandleRList(instr, true);
2681   } else {
2682     // Format(instr, "stm'cond'pu 'rn'w, 'rlist");
2683     HandleRList(instr, false);
2684   }
2685 }
2686
2687
2688 void Simulator::DecodeType5(Instruction* instr) {
2689   // Format(instr, "b'l'cond 'target");
2690   int off = (instr->SImmed24Value() << 2);
2691   intptr_t pc_address = get_pc();
2692   if (instr->HasLink()) {
2693     set_register(lr, pc_address + Instruction::kInstrSize);
2694   }
2695   int pc_reg = get_register(pc);
2696   set_pc(pc_reg + off);
2697 }
2698
2699
2700 void Simulator::DecodeType6(Instruction* instr) {
2701   DecodeType6CoprocessorIns(instr);
2702 }
2703
2704
2705 void Simulator::DecodeType7(Instruction* instr) {
2706   if (instr->Bit(24) == 1) {
2707     SoftwareInterrupt(instr);
2708   } else {
2709     DecodeTypeVFP(instr);
2710   }
2711 }
2712
2713
2714 // void Simulator::DecodeTypeVFP(Instruction* instr)
2715 // The Following ARMv7 VFPv instructions are currently supported.
2716 // vmov :Sn = Rt
2717 // vmov :Rt = Sn
2718 // vcvt: Dd = Sm
2719 // vcvt: Sd = Dm
2720 // Dd = vabs(Dm)
2721 // Dd = vneg(Dm)
2722 // Dd = vadd(Dn, Dm)
2723 // Dd = vsub(Dn, Dm)
2724 // Dd = vmul(Dn, Dm)
2725 // Dd = vdiv(Dn, Dm)
2726 // vcmp(Dd, Dm)
2727 // vmrs
2728 // Dd = vsqrt(Dm)
2729 void Simulator::DecodeTypeVFP(Instruction* instr) {
2730   ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
2731   ASSERT(instr->Bits(11, 9) == 0x5);
2732
2733   // Obtain double precision register codes.
2734   int vm = instr->VFPMRegValue(kDoublePrecision);
2735   int vd = instr->VFPDRegValue(kDoublePrecision);
2736   int vn = instr->VFPNRegValue(kDoublePrecision);
2737
2738   if (instr->Bit(4) == 0) {
2739     if (instr->Opc1Value() == 0x7) {
2740       // Other data processing instructions
2741       if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
2742         // vmov register to register.
2743         if (instr->SzValue() == 0x1) {
2744           int m = instr->VFPMRegValue(kDoublePrecision);
2745           int d = instr->VFPDRegValue(kDoublePrecision);
2746           set_d_register_from_double(d, get_double_from_d_register(m));
2747         } else {
2748           int m = instr->VFPMRegValue(kSinglePrecision);
2749           int d = instr->VFPDRegValue(kSinglePrecision);
2750           set_s_register_from_float(d, get_float_from_s_register(m));
2751         }
2752       } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
2753         // vabs
2754         double dm_value = get_double_from_d_register(vm);
2755         double dd_value = fabs(dm_value);
2756         set_d_register_from_double(vd, dd_value);
2757       } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
2758         // vneg
2759         double dm_value = get_double_from_d_register(vm);
2760         double dd_value = -dm_value;
2761         set_d_register_from_double(vd, dd_value);
2762       } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
2763         DecodeVCVTBetweenDoubleAndSingle(instr);
2764       } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
2765         DecodeVCVTBetweenFloatingPointAndInteger(instr);
2766       } else if (((instr->Opc2Value() >> 1) == 0x6) &&
2767                  (instr->Opc3Value() & 0x1)) {
2768         DecodeVCVTBetweenFloatingPointAndInteger(instr);
2769       } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
2770                  (instr->Opc3Value() & 0x1)) {
2771         DecodeVCMP(instr);
2772       } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
2773         // vsqrt
2774         double dm_value = get_double_from_d_register(vm);
2775         double dd_value = sqrt(dm_value);
2776         set_d_register_from_double(vd, dd_value);
2777       } else if (instr->Opc3Value() == 0x0) {
2778         // vmov immediate.
2779         if (instr->SzValue() == 0x1) {
2780           set_d_register_from_double(vd, instr->DoubleImmedVmov());
2781         } else {
2782           UNREACHABLE();  // Not used by v8.
2783         }
2784       } else {
2785         UNREACHABLE();  // Not used by V8.
2786       }
2787     } else if (instr->Opc1Value() == 0x3) {
2788       if (instr->SzValue() != 0x1) {
2789         UNREACHABLE();  // Not used by V8.
2790       }
2791
2792       if (instr->Opc3Value() & 0x1) {
2793         // vsub
2794         double dn_value = get_double_from_d_register(vn);
2795         double dm_value = get_double_from_d_register(vm);
2796         double dd_value = dn_value - dm_value;
2797         set_d_register_from_double(vd, dd_value);
2798       } else {
2799         // vadd
2800         double dn_value = get_double_from_d_register(vn);
2801         double dm_value = get_double_from_d_register(vm);
2802         double dd_value = dn_value + dm_value;
2803         set_d_register_from_double(vd, dd_value);
2804       }
2805     } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
2806       // vmul
2807       if (instr->SzValue() != 0x1) {
2808         UNREACHABLE();  // Not used by V8.
2809       }
2810
2811       double dn_value = get_double_from_d_register(vn);
2812       double dm_value = get_double_from_d_register(vm);
2813       double dd_value = dn_value * dm_value;
2814       set_d_register_from_double(vd, dd_value);
2815     } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
2816       // vdiv
2817       if (instr->SzValue() != 0x1) {
2818         UNREACHABLE();  // Not used by V8.
2819       }
2820
2821       double dn_value = get_double_from_d_register(vn);
2822       double dm_value = get_double_from_d_register(vm);
2823       double dd_value = dn_value / dm_value;
2824       div_zero_vfp_flag_ = (dm_value == 0);
2825       set_d_register_from_double(vd, dd_value);
2826     } else {
2827       UNIMPLEMENTED();  // Not used by V8.
2828     }
2829   } else {
2830     if ((instr->VCValue() == 0x0) &&
2831         (instr->VAValue() == 0x0)) {
2832       DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
2833     } else if ((instr->VLValue() == 0x1) &&
2834                (instr->VCValue() == 0x0) &&
2835                (instr->VAValue() == 0x7) &&
2836                (instr->Bits(19, 16) == 0x1)) {
2837       // vmrs
2838       uint32_t rt = instr->RtValue();
2839       if (rt == 0xF) {
2840         Copy_FPSCR_to_APSR();
2841       } else {
2842         // Emulate FPSCR from the Simulator flags.
2843         uint32_t fpscr = (n_flag_FPSCR_ << 31) |
2844                          (z_flag_FPSCR_ << 30) |
2845                          (c_flag_FPSCR_ << 29) |
2846                          (v_flag_FPSCR_ << 28) |
2847                          (inexact_vfp_flag_ << 4) |
2848                          (underflow_vfp_flag_ << 3) |
2849                          (overflow_vfp_flag_ << 2) |
2850                          (div_zero_vfp_flag_ << 1) |
2851                          (inv_op_vfp_flag_ << 0) |
2852                          (FPSCR_rounding_mode_);
2853         set_register(rt, fpscr);
2854       }
2855     } else if ((instr->VLValue() == 0x0) &&
2856                (instr->VCValue() == 0x0) &&
2857                (instr->VAValue() == 0x7) &&
2858                (instr->Bits(19, 16) == 0x1)) {
2859       // vmsr
2860       uint32_t rt = instr->RtValue();
2861       if (rt == pc) {
2862         UNREACHABLE();
2863       } else {
2864         uint32_t rt_value = get_register(rt);
2865         n_flag_FPSCR_ = (rt_value >> 31) & 1;
2866         z_flag_FPSCR_ = (rt_value >> 30) & 1;
2867         c_flag_FPSCR_ = (rt_value >> 29) & 1;
2868         v_flag_FPSCR_ = (rt_value >> 28) & 1;
2869         inexact_vfp_flag_ = (rt_value >> 4) & 1;
2870         underflow_vfp_flag_ = (rt_value >> 3) & 1;
2871         overflow_vfp_flag_ = (rt_value >> 2) & 1;
2872         div_zero_vfp_flag_ = (rt_value >> 1) & 1;
2873         inv_op_vfp_flag_ = (rt_value >> 0) & 1;
2874         FPSCR_rounding_mode_ =
2875             static_cast<VFPRoundingMode>((rt_value) & kVFPRoundingModeMask);
2876       }
2877     } else {
2878       UNIMPLEMENTED();  // Not used by V8.
2879     }
2880   }
2881 }
2882
2883
2884 void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
2885     Instruction* instr) {
2886   ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
2887          (instr->VAValue() == 0x0));
2888
2889   int t = instr->RtValue();
2890   int n = instr->VFPNRegValue(kSinglePrecision);
2891   bool to_arm_register = (instr->VLValue() == 0x1);
2892
2893   if (to_arm_register) {
2894     int32_t int_value = get_sinteger_from_s_register(n);
2895     set_register(t, int_value);
2896   } else {
2897     int32_t rs_val = get_register(t);
2898     set_s_register_from_sinteger(n, rs_val);
2899   }
2900 }
2901
2902
2903 void Simulator::DecodeVCMP(Instruction* instr) {
2904   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
2905   ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
2906          (instr->Opc3Value() & 0x1));
2907   // Comparison.
2908
2909   VFPRegPrecision precision = kSinglePrecision;
2910   if (instr->SzValue() == 1) {
2911     precision = kDoublePrecision;
2912   }
2913
2914   int d = instr->VFPDRegValue(precision);
2915   int m = 0;
2916   if (instr->Opc2Value() == 0x4) {
2917     m = instr->VFPMRegValue(precision);
2918   }
2919
2920   if (precision == kDoublePrecision) {
2921     double dd_value = get_double_from_d_register(d);
2922     double dm_value = 0.0;
2923     if (instr->Opc2Value() == 0x4) {
2924       dm_value = get_double_from_d_register(m);
2925     }
2926
2927     // Raise exceptions for quiet NaNs if necessary.
2928     if (instr->Bit(7) == 1) {
2929       if (isnan(dd_value)) {
2930         inv_op_vfp_flag_ = true;
2931       }
2932     }
2933
2934     Compute_FPSCR_Flags(dd_value, dm_value);
2935   } else {
2936     UNIMPLEMENTED();  // Not used by V8.
2937   }
2938 }
2939
2940
2941 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
2942   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
2943   ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
2944
2945   VFPRegPrecision dst_precision = kDoublePrecision;
2946   VFPRegPrecision src_precision = kSinglePrecision;
2947   if (instr->SzValue() == 1) {
2948     dst_precision = kSinglePrecision;
2949     src_precision = kDoublePrecision;
2950   }
2951
2952   int dst = instr->VFPDRegValue(dst_precision);
2953   int src = instr->VFPMRegValue(src_precision);
2954
2955   if (dst_precision == kSinglePrecision) {
2956     double val = get_double_from_d_register(src);
2957     set_s_register_from_float(dst, static_cast<float>(val));
2958   } else {
2959     float val = get_float_from_s_register(src);
2960     set_d_register_from_double(dst, static_cast<double>(val));
2961   }
2962 }
2963
2964 bool get_inv_op_vfp_flag(VFPRoundingMode mode,
2965                          double val,
2966                          bool unsigned_) {
2967   ASSERT((mode == RN) || (mode == RM) || (mode == RZ));
2968   double max_uint = static_cast<double>(0xffffffffu);
2969   double max_int = static_cast<double>(kMaxInt);
2970   double min_int = static_cast<double>(kMinInt);
2971
2972   // Check for NaN.
2973   if (val != val) {
2974     return true;
2975   }
2976
2977   // Check for overflow. This code works because 32bit integers can be
2978   // exactly represented by ieee-754 64bit floating-point values.
2979   switch (mode) {
2980     case RN:
2981       return  unsigned_ ? (val >= (max_uint + 0.5)) ||
2982                           (val < -0.5)
2983                         : (val >= (max_int + 0.5)) ||
2984                           (val < (min_int - 0.5));
2985
2986     case RM:
2987       return  unsigned_ ? (val >= (max_uint + 1.0)) ||
2988                           (val < 0)
2989                         : (val >= (max_int + 1.0)) ||
2990                           (val < min_int);
2991
2992     case RZ:
2993       return  unsigned_ ? (val >= (max_uint + 1.0)) ||
2994                           (val <= -1)
2995                         : (val >= (max_int + 1.0)) ||
2996                           (val <= (min_int - 1.0));
2997     default:
2998       UNREACHABLE();
2999       return true;
3000   }
3001 }
3002
3003
3004 // We call this function only if we had a vfp invalid exception.
3005 // It returns the correct saturated value.
3006 int VFPConversionSaturate(double val, bool unsigned_res) {
3007   if (val != val) {
3008     return 0;
3009   } else {
3010     if (unsigned_res) {
3011       return (val < 0) ? 0 : 0xffffffffu;
3012     } else {
3013       return (val < 0) ? kMinInt : kMaxInt;
3014     }
3015   }
3016 }
3017
3018
3019 void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
3020   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7) &&
3021          (instr->Bits(27, 23) == 0x1D));
3022   ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
3023          (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
3024
3025   // Conversion between floating-point and integer.
3026   bool to_integer = (instr->Bit(18) == 1);
3027
3028   VFPRegPrecision src_precision = (instr->SzValue() == 1) ? kDoublePrecision
3029                                                           : kSinglePrecision;
3030
3031   if (to_integer) {
3032     // We are playing with code close to the C++ standard's limits below,
3033     // hence the very simple code and heavy checks.
3034     //
3035     // Note:
3036     // C++ defines default type casting from floating point to integer as
3037     // (close to) rounding toward zero ("fractional part discarded").
3038
3039     int dst = instr->VFPDRegValue(kSinglePrecision);
3040     int src = instr->VFPMRegValue(src_precision);
3041
3042     // Bit 7 in vcvt instructions indicates if we should use the FPSCR rounding
3043     // mode or the default Round to Zero mode.
3044     VFPRoundingMode mode = (instr->Bit(7) != 1) ? FPSCR_rounding_mode_
3045                                                 : RZ;
3046     ASSERT((mode == RM) || (mode == RZ) || (mode == RN));
3047
3048     bool unsigned_integer = (instr->Bit(16) == 0);
3049     bool double_precision = (src_precision == kDoublePrecision);
3050
3051     double val = double_precision ? get_double_from_d_register(src)
3052                                   : get_float_from_s_register(src);
3053
3054     int temp = unsigned_integer ? static_cast<uint32_t>(val)
3055                                 : static_cast<int32_t>(val);
3056
3057     inv_op_vfp_flag_ = get_inv_op_vfp_flag(mode, val, unsigned_integer);
3058
3059     double abs_diff =
3060       unsigned_integer ? fabs(val - static_cast<uint32_t>(temp))
3061                        : fabs(val - temp);
3062
3063     inexact_vfp_flag_ = (abs_diff != 0);
3064
3065     if (inv_op_vfp_flag_) {
3066       temp = VFPConversionSaturate(val, unsigned_integer);
3067     } else {
3068       switch (mode) {
3069         case RN: {
3070           int val_sign = (val > 0) ? 1 : -1;
3071           if (abs_diff > 0.5) {
3072             temp += val_sign;
3073           } else if (abs_diff == 0.5) {
3074             // Round to even if exactly halfway.
3075             temp = ((temp % 2) == 0) ? temp : temp + val_sign;
3076           }
3077           break;
3078         }
3079
3080         case RM:
3081           temp = temp > val ? temp - 1 : temp;
3082           break;
3083
3084         case RZ:
3085           // Nothing to do.
3086           break;
3087
3088         default:
3089           UNREACHABLE();
3090       }
3091     }
3092
3093     // Update the destination register.
3094     set_s_register_from_sinteger(dst, temp);
3095
3096   } else {
3097     bool unsigned_integer = (instr->Bit(7) == 0);
3098
3099     int dst = instr->VFPDRegValue(src_precision);
3100     int src = instr->VFPMRegValue(kSinglePrecision);
3101
3102     int val = get_sinteger_from_s_register(src);
3103
3104     if (src_precision == kDoublePrecision) {
3105       if (unsigned_integer) {
3106         set_d_register_from_double(dst,
3107                                    static_cast<double>((uint32_t)val));
3108       } else {
3109         set_d_register_from_double(dst, static_cast<double>(val));
3110       }
3111     } else {
3112       if (unsigned_integer) {
3113         set_s_register_from_float(dst,
3114                                   static_cast<float>((uint32_t)val));
3115       } else {
3116         set_s_register_from_float(dst, static_cast<float>(val));
3117       }
3118     }
3119   }
3120 }
3121
3122
3123 // void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
3124 // Decode Type 6 coprocessor instructions.
3125 // Dm = vmov(Rt, Rt2)
3126 // <Rt, Rt2> = vmov(Dm)
3127 // Ddst = MEM(Rbase + 4*offset).
3128 // MEM(Rbase + 4*offset) = Dsrc.
3129 void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
3130   ASSERT((instr->TypeValue() == 6));
3131
3132   if (instr->CoprocessorValue() == 0xA) {
3133     switch (instr->OpcodeValue()) {
3134       case 0x8:
3135       case 0xA:
3136       case 0xC:
3137       case 0xE: {  // Load and store single precision float to memory.
3138         int rn = instr->RnValue();
3139         int vd = instr->VFPDRegValue(kSinglePrecision);
3140         int offset = instr->Immed8Value();
3141         if (!instr->HasU()) {
3142           offset = -offset;
3143         }
3144
3145         int32_t address = get_register(rn) + 4 * offset;
3146         if (instr->HasL()) {
3147           // Load double from memory: vldr.
3148           set_s_register_from_sinteger(vd, ReadW(address, instr));
3149         } else {
3150           // Store double to memory: vstr.
3151           WriteW(address, get_sinteger_from_s_register(vd), instr);
3152         }
3153         break;
3154       }
3155       case 0x4:
3156       case 0x5:
3157       case 0x6:
3158       case 0x7:
3159       case 0x9:
3160       case 0xB:
3161         // Load/store multiple single from memory: vldm/vstm.
3162         HandleVList(instr);
3163         break;
3164       default:
3165         UNIMPLEMENTED();  // Not used by V8.
3166     }
3167   } else if (instr->CoprocessorValue() == 0xB) {
3168     switch (instr->OpcodeValue()) {
3169       case 0x2:
3170         // Load and store double to two GP registers
3171         if (instr->Bits(7, 4) != 0x1) {
3172           UNIMPLEMENTED();  // Not used by V8.
3173         } else {
3174           int rt = instr->RtValue();
3175           int rn = instr->RnValue();
3176           int vm = instr->VmValue();
3177           if (instr->HasL()) {
3178             int32_t rt_int_value = get_sinteger_from_s_register(2*vm);
3179             int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1);
3180
3181             set_register(rt, rt_int_value);
3182             set_register(rn, rn_int_value);
3183           } else {
3184             int32_t rs_val = get_register(rt);
3185             int32_t rn_val = get_register(rn);
3186
3187             set_s_register_from_sinteger(2*vm, rs_val);
3188             set_s_register_from_sinteger((2*vm+1), rn_val);
3189           }
3190         }
3191         break;
3192       case 0x8:
3193       case 0xC: {  // Load and store double to memory.
3194         int rn = instr->RnValue();
3195         int vd = instr->VdValue();
3196         int offset = instr->Immed8Value();
3197         if (!instr->HasU()) {
3198           offset = -offset;
3199         }
3200         int32_t address = get_register(rn) + 4 * offset;
3201         if (instr->HasL()) {
3202           // Load double from memory: vldr.
3203           set_s_register_from_sinteger(2*vd, ReadW(address, instr));
3204           set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr));
3205         } else {
3206           // Store double to memory: vstr.
3207           WriteW(address, get_sinteger_from_s_register(2*vd), instr);
3208           WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr);
3209         }
3210         break;
3211       }
3212       case 0x4:
3213       case 0x5:
3214       case 0x9:
3215         // Load/store multiple double from memory: vldm/vstm.
3216         HandleVList(instr);
3217         break;
3218       default:
3219         UNIMPLEMENTED();  // Not used by V8.
3220     }
3221   } else {
3222     UNIMPLEMENTED();  // Not used by V8.
3223   }
3224 }
3225
3226
3227 // Executes the current instruction.
3228 void Simulator::InstructionDecode(Instruction* instr) {
3229   if (v8::internal::FLAG_check_icache) {
3230     CheckICache(isolate_->simulator_i_cache(), instr);
3231   }
3232   pc_modified_ = false;
3233   if (::v8::internal::FLAG_trace_sim) {
3234     disasm::NameConverter converter;
3235     disasm::Disassembler dasm(converter);
3236     // use a reasonably large buffer
3237     v8::internal::EmbeddedVector<char, 256> buffer;
3238     dasm.InstructionDecode(buffer,
3239                            reinterpret_cast<byte*>(instr));
3240     PrintF("  0x%08x  %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
3241   }
3242   if (instr->ConditionField() == kSpecialCondition) {
3243     UNIMPLEMENTED();
3244   } else if (ConditionallyExecute(instr)) {
3245     switch (instr->TypeValue()) {
3246       case 0:
3247       case 1: {
3248         DecodeType01(instr);
3249         break;
3250       }
3251       case 2: {
3252         DecodeType2(instr);
3253         break;
3254       }
3255       case 3: {
3256         DecodeType3(instr);
3257         break;
3258       }
3259       case 4: {
3260         DecodeType4(instr);
3261         break;
3262       }
3263       case 5: {
3264         DecodeType5(instr);
3265         break;
3266       }
3267       case 6: {
3268         DecodeType6(instr);
3269         break;
3270       }
3271       case 7: {
3272         DecodeType7(instr);
3273         break;
3274       }
3275       default: {
3276         UNIMPLEMENTED();
3277         break;
3278       }
3279     }
3280   // If the instruction is a non taken conditional stop, we need to skip the
3281   // inlined message address.
3282   } else if (instr->IsStop()) {
3283     set_pc(get_pc() + 2 * Instruction::kInstrSize);
3284   }
3285   if (!pc_modified_) {
3286     set_register(pc, reinterpret_cast<int32_t>(instr)
3287                          + Instruction::kInstrSize);
3288   }
3289 }
3290
3291
3292 void Simulator::Execute() {
3293   // Get the PC to simulate. Cannot use the accessor here as we need the
3294   // raw PC value and not the one used as input to arithmetic instructions.
3295   int program_counter = get_pc();
3296
3297   if (::v8::internal::FLAG_stop_sim_at == 0) {
3298     // Fast version of the dispatch loop without checking whether the simulator
3299     // should be stopping at a particular executed instruction.
3300     while (program_counter != end_sim_pc) {
3301       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
3302       icount_++;
3303       InstructionDecode(instr);
3304       program_counter = get_pc();
3305     }
3306   } else {
3307     // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
3308     // we reach the particular instuction count.
3309     while (program_counter != end_sim_pc) {
3310       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
3311       icount_++;
3312       if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
3313         ArmDebugger dbg(this);
3314         dbg.Debug();
3315       } else {
3316         InstructionDecode(instr);
3317       }
3318       program_counter = get_pc();
3319     }
3320   }
3321 }
3322
3323
3324 int32_t Simulator::Call(byte* entry, int argument_count, ...) {
3325   va_list parameters;
3326   va_start(parameters, argument_count);
3327   // Set up arguments
3328
3329   // First four arguments passed in registers.
3330   ASSERT(argument_count >= 4);
3331   set_register(r0, va_arg(parameters, int32_t));
3332   set_register(r1, va_arg(parameters, int32_t));
3333   set_register(r2, va_arg(parameters, int32_t));
3334   set_register(r3, va_arg(parameters, int32_t));
3335
3336   // Remaining arguments passed on stack.
3337   int original_stack = get_register(sp);
3338   // Compute position of stack on entry to generated code.
3339   int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));
3340   if (OS::ActivationFrameAlignment() != 0) {
3341     entry_stack &= -OS::ActivationFrameAlignment();
3342   }
3343   // Store remaining arguments on stack, from low to high memory.
3344   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
3345   for (int i = 4; i < argument_count; i++) {
3346     stack_argument[i - 4] = va_arg(parameters, int32_t);
3347   }
3348   va_end(parameters);
3349   set_register(sp, entry_stack);
3350
3351   // Prepare to execute the code at entry
3352   set_register(pc, reinterpret_cast<int32_t>(entry));
3353   // Put down marker for end of simulation. The simulator will stop simulation
3354   // when the PC reaches this value. By saving the "end simulation" value into
3355   // the LR the simulation stops when returning to this call point.
3356   set_register(lr, end_sim_pc);
3357
3358   // Remember the values of callee-saved registers.
3359   // The code below assumes that r9 is not used as sb (static base) in
3360   // simulator code and therefore is regarded as a callee-saved register.
3361   int32_t r4_val = get_register(r4);
3362   int32_t r5_val = get_register(r5);
3363   int32_t r6_val = get_register(r6);
3364   int32_t r7_val = get_register(r7);
3365   int32_t r8_val = get_register(r8);
3366   int32_t r9_val = get_register(r9);
3367   int32_t r10_val = get_register(r10);
3368   int32_t r11_val = get_register(r11);
3369
3370   // Set up the callee-saved registers with a known value. To be able to check
3371   // that they are preserved properly across JS execution.
3372   int32_t callee_saved_value = icount_;
3373   set_register(r4, callee_saved_value);
3374   set_register(r5, callee_saved_value);
3375   set_register(r6, callee_saved_value);
3376   set_register(r7, callee_saved_value);
3377   set_register(r8, callee_saved_value);
3378   set_register(r9, callee_saved_value);
3379   set_register(r10, callee_saved_value);
3380   set_register(r11, callee_saved_value);
3381
3382   // Start the simulation
3383   Execute();
3384
3385   // Check that the callee-saved registers have been preserved.
3386   CHECK_EQ(callee_saved_value, get_register(r4));
3387   CHECK_EQ(callee_saved_value, get_register(r5));
3388   CHECK_EQ(callee_saved_value, get_register(r6));
3389   CHECK_EQ(callee_saved_value, get_register(r7));
3390   CHECK_EQ(callee_saved_value, get_register(r8));
3391   CHECK_EQ(callee_saved_value, get_register(r9));
3392   CHECK_EQ(callee_saved_value, get_register(r10));
3393   CHECK_EQ(callee_saved_value, get_register(r11));
3394
3395   // Restore callee-saved registers with the original value.
3396   set_register(r4, r4_val);
3397   set_register(r5, r5_val);
3398   set_register(r6, r6_val);
3399   set_register(r7, r7_val);
3400   set_register(r8, r8_val);
3401   set_register(r9, r9_val);
3402   set_register(r10, r10_val);
3403   set_register(r11, r11_val);
3404
3405   // Pop stack passed arguments.
3406   CHECK_EQ(entry_stack, get_register(sp));
3407   set_register(sp, original_stack);
3408
3409   int32_t result = get_register(r0);
3410   return result;
3411 }
3412
3413
3414 uintptr_t Simulator::PushAddress(uintptr_t address) {
3415   int new_sp = get_register(sp) - sizeof(uintptr_t);
3416   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
3417   *stack_slot = address;
3418   set_register(sp, new_sp);
3419   return new_sp;
3420 }
3421
3422
3423 uintptr_t Simulator::PopAddress() {
3424   int current_sp = get_register(sp);
3425   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
3426   uintptr_t address = *stack_slot;
3427   set_register(sp, current_sp + sizeof(uintptr_t));
3428   return address;
3429 }
3430
3431 } }  // namespace v8::internal
3432
3433 #endif  // USE_SIMULATOR
3434
3435 #endif  // V8_TARGET_ARCH_ARM