1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <stdarg.h>
6#include <stdlib.h>
7#include <cmath>
8
9#if V8_TARGET_ARCH_PPC
10
11#include "src/assembler.h"
12#include "src/base/bits.h"
13#include "src/codegen.h"
14#include "src/disasm.h"
15#include "src/ppc/constants-ppc.h"
16#include "src/ppc/frames-ppc.h"
17#include "src/ppc/simulator-ppc.h"
18#include "src/runtime/runtime-utils.h"
19
20#if defined(USE_SIMULATOR)
21
22// Only build the simulator if not compiling for real PPC hardware.
23namespace v8 {
24namespace internal {
25
26const auto GetRegConfig = RegisterConfiguration::Crankshaft;
27
28// This macro provides a platform independent use of sscanf. The reason for
29// SScanF not being implemented in a platform independent way through
30// ::v8::internal::OS in the same way as SNPrintF is that the
31// Windows C Run-Time Library does not provide vsscanf.
32#define SScanF sscanf  // NOLINT
33
34// The PPCDebugger class is used by the simulator while debugging simulated
35// PowerPC code.
36class PPCDebugger {
37 public:
38  explicit PPCDebugger(Simulator* sim) : sim_(sim) {}
39  ~PPCDebugger();
40
41  void Stop(Instruction* instr);
42  void Debug();
43
44 private:
45  static const Instr kBreakpointInstr = (TWI | 0x1f * B21);
46  static const Instr kNopInstr = (ORI);  // ori, 0,0,0
47
48  Simulator* sim_;
49
50  intptr_t GetRegisterValue(int regnum);
51  double GetRegisterPairDoubleValue(int regnum);
52  double GetFPDoubleRegisterValue(int regnum);
53  bool GetValue(const char* desc, intptr_t* value);
54  bool GetFPDoubleValue(const char* desc, double* value);
55
56  // Set or delete a breakpoint. Returns true if successful.
57  bool SetBreakpoint(Instruction* break_pc);
58  bool DeleteBreakpoint(Instruction* break_pc);
59
60  // Undo and redo all breakpoints. This is needed to bracket disassembly and
61  // execution to skip past breakpoints when run from the debugger.
62  void UndoBreakpoints();
63  void RedoBreakpoints();
64};
65
66
67PPCDebugger::~PPCDebugger() {}
68
69
70#ifdef GENERATED_CODE_COVERAGE
71static FILE* coverage_log = NULL;
72
73
74static void InitializeCoverage() {
75  char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
76  if (file_name != NULL) {
77    coverage_log = fopen(file_name, "aw+");
78  }
79}
80
81
82void PPCDebugger::Stop(Instruction* instr) {
83  // Get the stop code.
84  uint32_t code = instr->SvcValue() & kStopCodeMask;
85  // Retrieve the encoded address, which comes just after this stop.
86  char** msg_address =
87      reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
88  char* msg = *msg_address;
89  DCHECK(msg != NULL);
90
91  // Update this stop description.
92  if (isWatchedStop(code) && !watched_stops_[code].desc) {
93    watched_stops_[code].desc = msg;
94  }
95
96  if (strlen(msg) > 0) {
97    if (coverage_log != NULL) {
98      fprintf(coverage_log, "%s\n", msg);
99      fflush(coverage_log);
100    }
101    // Overwrite the instruction and address with nops.
102    instr->SetInstructionBits(kNopInstr);
103    reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
104  }
105  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize);
106}
107
108#else  // ndef GENERATED_CODE_COVERAGE
109
110static void InitializeCoverage() {}
111
112
113void PPCDebugger::Stop(Instruction* instr) {
114  // Get the stop code.
115  // use of kStopCodeMask not right on PowerPC
116  uint32_t code = instr->SvcValue() & kStopCodeMask;
117  // Retrieve the encoded address, which comes just after this stop.
118  char* msg =
119      *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
120  // Update this stop description.
121  if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
122    sim_->watched_stops_[code].desc = msg;
123  }
124  // Print the stop message and code if it is not the default code.
125  if (code != kMaxStopCode) {
126    PrintF("Simulator hit stop %u: %s\n", code, msg);
127  } else {
128    PrintF("Simulator hit %s\n", msg);
129  }
130  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize);
131  Debug();
132}
133#endif
134
135
136intptr_t PPCDebugger::GetRegisterValue(int regnum) {
137  return sim_->get_register(regnum);
138}
139
140
141double PPCDebugger::GetRegisterPairDoubleValue(int regnum) {
142  return sim_->get_double_from_register_pair(regnum);
143}
144
145
146double PPCDebugger::GetFPDoubleRegisterValue(int regnum) {
147  return sim_->get_double_from_d_register(regnum);
148}
149
150
151bool PPCDebugger::GetValue(const char* desc, intptr_t* value) {
152  int regnum = Registers::Number(desc);
153  if (regnum != kNoRegister) {
154    *value = GetRegisterValue(regnum);
155    return true;
156  } else {
157    if (strncmp(desc, "0x", 2) == 0) {
158      return SScanF(desc + 2, "%" V8PRIxPTR,
159                    reinterpret_cast<uintptr_t*>(value)) == 1;
160    } else {
161      return SScanF(desc, "%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) ==
162             1;
163    }
164  }
165  return false;
166}
167
168
169bool PPCDebugger::GetFPDoubleValue(const char* desc, double* value) {
170  int regnum = DoubleRegisters::Number(desc);
171  if (regnum != kNoRegister) {
172    *value = sim_->get_double_from_d_register(regnum);
173    return true;
174  }
175  return false;
176}
177
178
179bool PPCDebugger::SetBreakpoint(Instruction* break_pc) {
180  // Check if a breakpoint can be set. If not return without any side-effects.
181  if (sim_->break_pc_ != NULL) {
182    return false;
183  }
184
185  // Set the breakpoint.
186  sim_->break_pc_ = break_pc;
187  sim_->break_instr_ = break_pc->InstructionBits();
188  // Not setting the breakpoint instruction in the code itself. It will be set
189  // when the debugger shell continues.
190  return true;
191}
192
193
194bool PPCDebugger::DeleteBreakpoint(Instruction* break_pc) {
195  if (sim_->break_pc_ != NULL) {
196    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
197  }
198
199  sim_->break_pc_ = NULL;
200  sim_->break_instr_ = 0;
201  return true;
202}
203
204
205void PPCDebugger::UndoBreakpoints() {
206  if (sim_->break_pc_ != NULL) {
207    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
208  }
209}
210
211
212void PPCDebugger::RedoBreakpoints() {
213  if (sim_->break_pc_ != NULL) {
214    sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
215  }
216}
217
218
219void PPCDebugger::Debug() {
220  intptr_t last_pc = -1;
221  bool done = false;
222
223#define COMMAND_SIZE 63
224#define ARG_SIZE 255
225
226#define STR(a) #a
227#define XSTR(a) STR(a)
228
229  char cmd[COMMAND_SIZE + 1];
230  char arg1[ARG_SIZE + 1];
231  char arg2[ARG_SIZE + 1];
232  char* argv[3] = {cmd, arg1, arg2};
233
234  // make sure to have a proper terminating character if reaching the limit
235  cmd[COMMAND_SIZE] = 0;
236  arg1[ARG_SIZE] = 0;
237  arg2[ARG_SIZE] = 0;
238
239  // Undo all set breakpoints while running in the debugger shell. This will
240  // make them invisible to all commands.
241  UndoBreakpoints();
242  // Disable tracing while simulating
243  bool trace = ::v8::internal::FLAG_trace_sim;
244  ::v8::internal::FLAG_trace_sim = false;
245
246  while (!done && !sim_->has_bad_pc()) {
247    if (last_pc != sim_->get_pc()) {
248      disasm::NameConverter converter;
249      disasm::Disassembler dasm(converter);
250      // use a reasonably large buffer
251      v8::internal::EmbeddedVector<char, 256> buffer;
252      dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc()));
253      PrintF("  0x%08" V8PRIxPTR "  %s\n", sim_->get_pc(), buffer.start());
254      last_pc = sim_->get_pc();
255    }
256    char* line = ReadLine("sim> ");
257    if (line == NULL) {
258      break;
259    } else {
260      char* last_input = sim_->last_debugger_input();
261      if (strcmp(line, "\n") == 0 && last_input != NULL) {
262        line = last_input;
263      } else {
264        // Ownership is transferred to sim_;
265        sim_->set_last_debugger_input(line);
266      }
267      // Use sscanf to parse the individual parts of the command line. At the
268      // moment no command expects more than two parameters.
269      int argc = SScanF(line,
270                        "%" XSTR(COMMAND_SIZE) "s "
271                        "%" XSTR(ARG_SIZE) "s "
272                        "%" XSTR(ARG_SIZE) "s",
273                        cmd, arg1, arg2);
274      if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
275        intptr_t value;
276
277        // If at a breakpoint, proceed past it.
278        if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
279                ->InstructionBits() == 0x7d821008) {
280          sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
281        } else {
282          sim_->ExecuteInstruction(
283              reinterpret_cast<Instruction*>(sim_->get_pc()));
284        }
285
286        if (argc == 2 && last_pc != sim_->get_pc() && GetValue(arg1, &value)) {
287          for (int i = 1; i < value; i++) {
288            disasm::NameConverter converter;
289            disasm::Disassembler dasm(converter);
290            // use a reasonably large buffer
291            v8::internal::EmbeddedVector<char, 256> buffer;
292            dasm.InstructionDecode(buffer,
293                                   reinterpret_cast<byte*>(sim_->get_pc()));
294            PrintF("  0x%08" V8PRIxPTR "  %s\n", sim_->get_pc(),
295                   buffer.start());
296            sim_->ExecuteInstruction(
297                reinterpret_cast<Instruction*>(sim_->get_pc()));
298          }
299        }
300      } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
301        // If at a breakpoint, proceed past it.
302        if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
303                ->InstructionBits() == 0x7d821008) {
304          sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
305        } else {
306          // Execute the one instruction we broke at with breakpoints disabled.
307          sim_->ExecuteInstruction(
308              reinterpret_cast<Instruction*>(sim_->get_pc()));
309        }
310        // Leave the debugger shell.
311        done = true;
312      } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
313        if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) {
314          intptr_t value;
315          double dvalue;
316          if (strcmp(arg1, "all") == 0) {
317            for (int i = 0; i < kNumRegisters; i++) {
318              value = GetRegisterValue(i);
319              PrintF("    %3s: %08" V8PRIxPTR,
320                     GetRegConfig()->GetGeneralRegisterName(i), value);
321              if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
322                  (i % 2) == 0) {
323                dvalue = GetRegisterPairDoubleValue(i);
324                PrintF(" (%f)\n", dvalue);
325              } else if (i != 0 && !((i + 1) & 3)) {
326                PrintF("\n");
327              }
328            }
329            PrintF("  pc: %08" V8PRIxPTR "  lr: %08" V8PRIxPTR
330                   "  "
331                   "ctr: %08" V8PRIxPTR "  xer: %08x  cr: %08x\n",
332                   sim_->special_reg_pc_, sim_->special_reg_lr_,
333                   sim_->special_reg_ctr_, sim_->special_reg_xer_,
334                   sim_->condition_reg_);
335          } else if (strcmp(arg1, "alld") == 0) {
336            for (int i = 0; i < kNumRegisters; i++) {
337              value = GetRegisterValue(i);
338              PrintF("     %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
339                     GetRegConfig()->GetGeneralRegisterName(i), value, value);
340              if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
341                  (i % 2) == 0) {
342                dvalue = GetRegisterPairDoubleValue(i);
343                PrintF(" (%f)\n", dvalue);
344              } else if (!((i + 1) % 2)) {
345                PrintF("\n");
346              }
347            }
348            PrintF("   pc: %08" V8PRIxPTR "  lr: %08" V8PRIxPTR
349                   "  "
350                   "ctr: %08" V8PRIxPTR "  xer: %08x  cr: %08x\n",
351                   sim_->special_reg_pc_, sim_->special_reg_lr_,
352                   sim_->special_reg_ctr_, sim_->special_reg_xer_,
353                   sim_->condition_reg_);
354          } else if (strcmp(arg1, "allf") == 0) {
355            for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
356              dvalue = GetFPDoubleRegisterValue(i);
357              uint64_t as_words = bit_cast<uint64_t>(dvalue);
358              PrintF("%3s: %f 0x%08x %08x\n",
359                     GetRegConfig()->GetDoubleRegisterName(i), dvalue,
360                     static_cast<uint32_t>(as_words >> 32),
361                     static_cast<uint32_t>(as_words & 0xffffffff));
362            }
363          } else if (arg1[0] == 'r' &&
364                     (arg1[1] >= '0' && arg1[1] <= '9' &&
365                      (arg1[2] == '\0' || (arg1[2] >= '0' && arg1[2] <= '9' &&
366                                           arg1[3] == '\0')))) {
367            int regnum = strtoul(&arg1[1], 0, 10);
368            if (regnum != kNoRegister) {
369              value = GetRegisterValue(regnum);
370              PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
371                     value);
372            } else {
373              PrintF("%s unrecognized\n", arg1);
374            }
375          } else {
376            if (GetValue(arg1, &value)) {
377              PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
378                     value);
379            } else if (GetFPDoubleValue(arg1, &dvalue)) {
380              uint64_t as_words = bit_cast<uint64_t>(dvalue);
381              PrintF("%s: %f 0x%08x %08x\n", arg1, dvalue,
382                     static_cast<uint32_t>(as_words >> 32),
383                     static_cast<uint32_t>(as_words & 0xffffffff));
384            } else {
385              PrintF("%s unrecognized\n", arg1);
386            }
387          }
388        } else {
389          PrintF("print <register>\n");
390        }
391      } else if ((strcmp(cmd, "po") == 0) ||
392                 (strcmp(cmd, "printobject") == 0)) {
393        if (argc == 2) {
394          intptr_t value;
395          OFStream os(stdout);
396          if (GetValue(arg1, &value)) {
397            Object* obj = reinterpret_cast<Object*>(value);
398            os << arg1 << ": \n";
399#ifdef DEBUG
400            obj->Print(os);
401            os << "\n";
402#else
403            os << Brief(obj) << "\n";
404#endif
405          } else {
406            os << arg1 << " unrecognized\n";
407          }
408        } else {
409          PrintF("printobject <value>\n");
410        }
411      } else if (strcmp(cmd, "setpc") == 0) {
412        intptr_t value;
413
414        if (!GetValue(arg1, &value)) {
415          PrintF("%s unrecognized\n", arg1);
416          continue;
417        }
418        sim_->set_pc(value);
419      } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
420        intptr_t* cur = NULL;
421        intptr_t* end = NULL;
422        int next_arg = 1;
423
424        if (strcmp(cmd, "stack") == 0) {
425          cur = reinterpret_cast<intptr_t*>(sim_->get_register(Simulator::sp));
426        } else {  // "mem"
427          intptr_t value;
428          if (!GetValue(arg1, &value)) {
429            PrintF("%s unrecognized\n", arg1);
430            continue;
431          }
432          cur = reinterpret_cast<intptr_t*>(value);
433          next_arg++;
434        }
435
436        intptr_t words;  // likely inaccurate variable name for 64bit
437        if (argc == next_arg) {
438          words = 10;
439        } else {
440          if (!GetValue(argv[next_arg], &words)) {
441            words = 10;
442          }
443        }
444        end = cur + words;
445
446        while (cur < end) {
447          PrintF("  0x%08" V8PRIxPTR ":  0x%08" V8PRIxPTR " %10" V8PRIdPTR,
448                 reinterpret_cast<intptr_t>(cur), *cur, *cur);
449          HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
450          intptr_t value = *cur;
451          Heap* current_heap = sim_->isolate_->heap();
452          if (((value & 1) == 0) ||
453              current_heap->ContainsSlow(obj->address())) {
454            PrintF(" (");
455            if ((value & 1) == 0) {
456              PrintF("smi %d", PlatformSmiTagging::SmiToInt(obj));
457            } else {
458              obj->ShortPrint();
459            }
460            PrintF(")");
461          }
462          PrintF("\n");
463          cur++;
464        }
465      } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
466        disasm::NameConverter converter;
467        disasm::Disassembler dasm(converter);
468        // use a reasonably large buffer
469        v8::internal::EmbeddedVector<char, 256> buffer;
470
471        byte* prev = NULL;
472        byte* cur = NULL;
473        byte* end = NULL;
474
475        if (argc == 1) {
476          cur = reinterpret_cast<byte*>(sim_->get_pc());
477          end = cur + (10 * Instruction::kInstrSize);
478        } else if (argc == 2) {
479          int regnum = Registers::Number(arg1);
480          if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
481            // The argument is an address or a register name.
482            intptr_t value;
483            if (GetValue(arg1, &value)) {
484              cur = reinterpret_cast<byte*>(value);
485              // Disassemble 10 instructions at <arg1>.
486              end = cur + (10 * Instruction::kInstrSize);
487            }
488          } else {
489            // The argument is the number of instructions.
490            intptr_t value;
491            if (GetValue(arg1, &value)) {
492              cur = reinterpret_cast<byte*>(sim_->get_pc());
493              // Disassemble <arg1> instructions.
494              end = cur + (value * Instruction::kInstrSize);
495            }
496          }
497        } else {
498          intptr_t value1;
499          intptr_t value2;
500          if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
501            cur = reinterpret_cast<byte*>(value1);
502            end = cur + (value2 * Instruction::kInstrSize);
503          }
504        }
505
506        while (cur < end) {
507          prev = cur;
508          cur += dasm.InstructionDecode(buffer, cur);
509          PrintF("  0x%08" V8PRIxPTR "  %s\n", reinterpret_cast<intptr_t>(prev),
510                 buffer.start());
511        }
512      } else if (strcmp(cmd, "gdb") == 0) {
513        PrintF("relinquishing control to gdb\n");
514        v8::base::OS::DebugBreak();
515        PrintF("regaining control from gdb\n");
516      } else if (strcmp(cmd, "break") == 0) {
517        if (argc == 2) {
518          intptr_t value;
519          if (GetValue(arg1, &value)) {
520            if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
521              PrintF("setting breakpoint failed\n");
522            }
523          } else {
524            PrintF("%s unrecognized\n", arg1);
525          }
526        } else {
527          PrintF("break <address>\n");
528        }
529      } else if (strcmp(cmd, "del") == 0) {
530        if (!DeleteBreakpoint(NULL)) {
531          PrintF("deleting breakpoint failed\n");
532        }
533      } else if (strcmp(cmd, "cr") == 0) {
534        PrintF("Condition reg: %08x\n", sim_->condition_reg_);
535      } else if (strcmp(cmd, "lr") == 0) {
536        PrintF("Link reg: %08" V8PRIxPTR "\n", sim_->special_reg_lr_);
537      } else if (strcmp(cmd, "ctr") == 0) {
538        PrintF("Ctr reg: %08" V8PRIxPTR "\n", sim_->special_reg_ctr_);
539      } else if (strcmp(cmd, "xer") == 0) {
540        PrintF("XER: %08x\n", sim_->special_reg_xer_);
541      } else if (strcmp(cmd, "fpscr") == 0) {
542        PrintF("FPSCR: %08x\n", sim_->fp_condition_reg_);
543      } else if (strcmp(cmd, "stop") == 0) {
544        intptr_t value;
545        intptr_t stop_pc =
546            sim_->get_pc() - (Instruction::kInstrSize + kPointerSize);
547        Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
548        Instruction* msg_address =
549            reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize);
550        if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
551          // Remove the current stop.
552          if (sim_->isStopInstruction(stop_instr)) {
553            stop_instr->SetInstructionBits(kNopInstr);
554            msg_address->SetInstructionBits(kNopInstr);
555          } else {
556            PrintF("Not at debugger stop.\n");
557          }
558        } else if (argc == 3) {
559          // Print information about all/the specified breakpoint(s).
560          if (strcmp(arg1, "info") == 0) {
561            if (strcmp(arg2, "all") == 0) {
562              PrintF("Stop information:\n");
563              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
564                sim_->PrintStopInfo(i);
565              }
566            } else if (GetValue(arg2, &value)) {
567              sim_->PrintStopInfo(value);
568            } else {
569              PrintF("Unrecognized argument.\n");
570            }
571          } else if (strcmp(arg1, "enable") == 0) {
572            // Enable all/the specified breakpoint(s).
573            if (strcmp(arg2, "all") == 0) {
574              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
575                sim_->EnableStop(i);
576              }
577            } else if (GetValue(arg2, &value)) {
578              sim_->EnableStop(value);
579            } else {
580              PrintF("Unrecognized argument.\n");
581            }
582          } else if (strcmp(arg1, "disable") == 0) {
583            // Disable all/the specified breakpoint(s).
584            if (strcmp(arg2, "all") == 0) {
585              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
586                sim_->DisableStop(i);
587              }
588            } else if (GetValue(arg2, &value)) {
589              sim_->DisableStop(value);
590            } else {
591              PrintF("Unrecognized argument.\n");
592            }
593          }
594        } else {
595          PrintF("Wrong usage. Use help command for more information.\n");
596        }
597      } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
598        ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
599        PrintF("Trace of executed instructions is %s\n",
600               ::v8::internal::FLAG_trace_sim ? "on" : "off");
601      } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
602        PrintF("cont\n");
603        PrintF("  continue execution (alias 'c')\n");
604        PrintF("stepi [num instructions]\n");
605        PrintF("  step one/num instruction(s) (alias 'si')\n");
606        PrintF("print <register>\n");
607        PrintF("  print register content (alias 'p')\n");
608        PrintF("  use register name 'all' to display all integer registers\n");
609        PrintF(
610            "  use register name 'alld' to display integer registers "
611            "with decimal values\n");
612        PrintF("  use register name 'rN' to display register number 'N'\n");
613        PrintF("  add argument 'fp' to print register pair double values\n");
614        PrintF(
615            "  use register name 'allf' to display floating-point "
616            "registers\n");
617        PrintF("printobject <register>\n");
618        PrintF("  print an object from a register (alias 'po')\n");
619        PrintF("cr\n");
620        PrintF("  print condition register\n");
621        PrintF("lr\n");
622        PrintF("  print link register\n");
623        PrintF("ctr\n");
624        PrintF("  print ctr register\n");
625        PrintF("xer\n");
626        PrintF("  print XER\n");
627        PrintF("fpscr\n");
628        PrintF("  print FPSCR\n");
629        PrintF("stack [<num words>]\n");
630        PrintF("  dump stack content, default dump 10 words)\n");
631        PrintF("mem <address> [<num words>]\n");
632        PrintF("  dump memory content, default dump 10 words)\n");
633        PrintF("disasm [<instructions>]\n");
634        PrintF("disasm [<address/register>]\n");
635        PrintF("disasm [[<address/register>] <instructions>]\n");
636        PrintF("  disassemble code, default is 10 instructions\n");
637        PrintF("  from pc (alias 'di')\n");
638        PrintF("gdb\n");
639        PrintF("  enter gdb\n");
640        PrintF("break <address>\n");
641        PrintF("  set a break point on the address\n");
642        PrintF("del\n");
643        PrintF("  delete the breakpoint\n");
644        PrintF("trace (alias 't')\n");
645        PrintF("  toogle the tracing of all executed statements\n");
646        PrintF("stop feature:\n");
647        PrintF("  Description:\n");
648        PrintF("    Stops are debug instructions inserted by\n");
649        PrintF("    the Assembler::stop() function.\n");
650        PrintF("    When hitting a stop, the Simulator will\n");
651        PrintF("    stop and and give control to the PPCDebugger.\n");
652        PrintF("    The first %d stop codes are watched:\n",
653               Simulator::kNumOfWatchedStops);
654        PrintF("    - They can be enabled / disabled: the Simulator\n");
655        PrintF("      will / won't stop when hitting them.\n");
656        PrintF("    - The Simulator keeps track of how many times they \n");
657        PrintF("      are met. (See the info command.) Going over a\n");
658        PrintF("      disabled stop still increases its counter. \n");
659        PrintF("  Commands:\n");
660        PrintF("    stop info all/<code> : print infos about number <code>\n");
661        PrintF("      or all stop(s).\n");
662        PrintF("    stop enable/disable all/<code> : enables / disables\n");
663        PrintF("      all or number <code> stop(s)\n");
664        PrintF("    stop unstop\n");
665        PrintF("      ignore the stop instruction at the current location\n");
666        PrintF("      from now on\n");
667      } else {
668        PrintF("Unknown command: %s\n", cmd);
669      }
670    }
671  }
672
673  // Add all the breakpoints back to stop execution and enter the debugger
674  // shell when hit.
675  RedoBreakpoints();
676  // Restore tracing
677  ::v8::internal::FLAG_trace_sim = trace;
678
679#undef COMMAND_SIZE
680#undef ARG_SIZE
681
682#undef STR
683#undef XSTR
684}
685
686
687static bool ICacheMatch(void* one, void* two) {
688  DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
689  DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
690  return one == two;
691}
692
693
694static uint32_t ICacheHash(void* key) {
695  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
696}
697
698
699static bool AllOnOnePage(uintptr_t start, int size) {
700  intptr_t start_page = (start & ~CachePage::kPageMask);
701  intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
702  return start_page == end_page;
703}
704
705
706void Simulator::set_last_debugger_input(char* input) {
707  DeleteArray(last_debugger_input_);
708  last_debugger_input_ = input;
709}
710
711
712void Simulator::FlushICache(base::HashMap* i_cache, void* start_addr,
713                            size_t size) {
714  intptr_t start = reinterpret_cast<intptr_t>(start_addr);
715  int intra_line = (start & CachePage::kLineMask);
716  start -= intra_line;
717  size += intra_line;
718  size = ((size - 1) | CachePage::kLineMask) + 1;
719  int offset = (start & CachePage::kPageMask);
720  while (!AllOnOnePage(start, size - 1)) {
721    int bytes_to_flush = CachePage::kPageSize - offset;
722    FlushOnePage(i_cache, start, bytes_to_flush);
723    start += bytes_to_flush;
724    size -= bytes_to_flush;
725    DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask));
726    offset = 0;
727  }
728  if (size != 0) {
729    FlushOnePage(i_cache, start, size);
730  }
731}
732
733
734CachePage* Simulator::GetCachePage(base::HashMap* i_cache, void* page) {
735  base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page));
736  if (entry->value == NULL) {
737    CachePage* new_page = new CachePage();
738    entry->value = new_page;
739  }
740  return reinterpret_cast<CachePage*>(entry->value);
741}
742
743
744// Flush from start up to and not including start + size.
745void Simulator::FlushOnePage(base::HashMap* i_cache, intptr_t start, int size) {
746  DCHECK(size <= CachePage::kPageSize);
747  DCHECK(AllOnOnePage(start, size - 1));
748  DCHECK((start & CachePage::kLineMask) == 0);
749  DCHECK((size & CachePage::kLineMask) == 0);
750  void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
751  int offset = (start & CachePage::kPageMask);
752  CachePage* cache_page = GetCachePage(i_cache, page);
753  char* valid_bytemap = cache_page->ValidityByte(offset);
754  memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
755}
756
757void Simulator::CheckICache(base::HashMap* i_cache, Instruction* instr) {
758  intptr_t address = reinterpret_cast<intptr_t>(instr);
759  void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
760  void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
761  int offset = (address & CachePage::kPageMask);
762  CachePage* cache_page = GetCachePage(i_cache, page);
763  char* cache_valid_byte = cache_page->ValidityByte(offset);
764  bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
765  char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
766  if (cache_hit) {
767    // Check that the data in memory matches the contents of the I-cache.
768    CHECK_EQ(0,
769             memcmp(reinterpret_cast<void*>(instr),
770                    cache_page->CachedData(offset), Instruction::kInstrSize));
771  } else {
772    // Cache miss.  Load memory into the cache.
773    memcpy(cached_line, line, CachePage::kLineLength);
774    *cache_valid_byte = CachePage::LINE_VALID;
775  }
776}
777
778
779void Simulator::Initialize(Isolate* isolate) {
780  if (isolate->simulator_initialized()) return;
781  isolate->set_simulator_initialized(true);
782  ::v8::internal::ExternalReference::set_redirector(isolate,
783                                                    &RedirectExternalReference);
784}
785
786
787Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
788  i_cache_ = isolate_->simulator_i_cache();
789  if (i_cache_ == NULL) {
790    i_cache_ = new base::HashMap(&ICacheMatch);
791    isolate_->set_simulator_i_cache(i_cache_);
792  }
793  Initialize(isolate);
794// Set up simulator support first. Some of this information is needed to
795// setup the architecture state.
796#if V8_TARGET_ARCH_PPC64
797  size_t stack_size = FLAG_sim_stack_size * KB;
798#else
799  size_t stack_size = MB;  // allocate 1MB for stack
800#endif
801  stack_size += 2 * stack_protection_size_;
802  stack_ = reinterpret_cast<char*>(malloc(stack_size));
803  pc_modified_ = false;
804  icount_ = 0;
805  break_pc_ = NULL;
806  break_instr_ = 0;
807
808  // Set up architecture state.
809  // All registers are initialized to zero to start with.
810  for (int i = 0; i < kNumGPRs; i++) {
811    registers_[i] = 0;
812  }
813  condition_reg_ = 0;
814  fp_condition_reg_ = 0;
815  special_reg_pc_ = 0;
816  special_reg_lr_ = 0;
817  special_reg_ctr_ = 0;
818
819  // Initializing FP registers.
820  for (int i = 0; i < kNumFPRs; i++) {
821    fp_registers_[i] = 0.0;
822  }
823
824  // The sp is initialized to point to the bottom (high address) of the
825  // allocated stack area. To be safe in potential stack underflows we leave
826  // some buffer below.
827  registers_[sp] =
828      reinterpret_cast<intptr_t>(stack_) + stack_size - stack_protection_size_;
829  InitializeCoverage();
830
831  last_debugger_input_ = NULL;
832}
833
834
835Simulator::~Simulator() { free(stack_); }
836
837
838// When the generated code calls an external reference we need to catch that in
839// the simulator.  The external reference will be a function compiled for the
840// host architecture.  We need to call that function instead of trying to
841// execute it with the simulator.  We do that by redirecting the external
842// reference to a svc (Supervisor Call) instruction that is handled by
843// the simulator.  We write the original destination of the jump just at a known
844// offset from the svc instruction so the simulator knows what to call.
845class Redirection {
846 public:
847  Redirection(Isolate* isolate, void* external_function,
848              ExternalReference::Type type)
849      : external_function_(external_function),
850        swi_instruction_(rtCallRedirInstr | kCallRtRedirected),
851        type_(type),
852        next_(NULL) {
853    next_ = isolate->simulator_redirection();
854    Simulator::current(isolate)->FlushICache(
855        isolate->simulator_i_cache(),
856        reinterpret_cast<void*>(&swi_instruction_), Instruction::kInstrSize);
857    isolate->set_simulator_redirection(this);
858    if (ABI_USES_FUNCTION_DESCRIPTORS) {
859      function_descriptor_[0] = reinterpret_cast<intptr_t>(&swi_instruction_);
860      function_descriptor_[1] = 0;
861      function_descriptor_[2] = 0;
862    }
863  }
864
865  void* address() {
866    if (ABI_USES_FUNCTION_DESCRIPTORS) {
867      return reinterpret_cast<void*>(function_descriptor_);
868    } else {
869      return reinterpret_cast<void*>(&swi_instruction_);
870    }
871  }
872
873  void* external_function() { return external_function_; }
874  ExternalReference::Type type() { return type_; }
875
876  static Redirection* Get(Isolate* isolate, void* external_function,
877                          ExternalReference::Type type) {
878    Redirection* current = isolate->simulator_redirection();
879    for (; current != NULL; current = current->next_) {
880      if (current->external_function_ == external_function) {
881        DCHECK_EQ(current->type(), type);
882        return current;
883      }
884    }
885    return new Redirection(isolate, external_function, type);
886  }
887
888  static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
889    char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
890    char* addr_of_redirection =
891        addr_of_swi - offsetof(Redirection, swi_instruction_);
892    return reinterpret_cast<Redirection*>(addr_of_redirection);
893  }
894
895  static Redirection* FromAddress(void* address) {
896    int delta = ABI_USES_FUNCTION_DESCRIPTORS
897                    ? offsetof(Redirection, function_descriptor_)
898                    : offsetof(Redirection, swi_instruction_);
899    char* addr_of_redirection = reinterpret_cast<char*>(address) - delta;
900    return reinterpret_cast<Redirection*>(addr_of_redirection);
901  }
902
903  static void* ReverseRedirection(intptr_t reg) {
904    Redirection* redirection = FromAddress(reinterpret_cast<void*>(reg));
905    return redirection->external_function();
906  }
907
908  static void DeleteChain(Redirection* redirection) {
909    while (redirection != nullptr) {
910      Redirection* next = redirection->next_;
911      delete redirection;
912      redirection = next;
913    }
914  }
915
916 private:
917  void* external_function_;
918  uint32_t swi_instruction_;
919  ExternalReference::Type type_;
920  Redirection* next_;
921  intptr_t function_descriptor_[3];
922};
923
924
925// static
926void Simulator::TearDown(base::HashMap* i_cache, Redirection* first) {
927  Redirection::DeleteChain(first);
928  if (i_cache != nullptr) {
929    for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
930         entry = i_cache->Next(entry)) {
931      delete static_cast<CachePage*>(entry->value);
932    }
933    delete i_cache;
934  }
935}
936
937
938void* Simulator::RedirectExternalReference(Isolate* isolate,
939                                           void* external_function,
940                                           ExternalReference::Type type) {
941  Redirection* redirection = Redirection::Get(isolate, external_function, type);
942  return redirection->address();
943}
944
945
946// Get the active Simulator for the current thread.
947Simulator* Simulator::current(Isolate* isolate) {
948  v8::internal::Isolate::PerIsolateThreadData* isolate_data =
949      isolate->FindOrAllocatePerThreadDataForThisThread();
950  DCHECK(isolate_data != NULL);
951
952  Simulator* sim = isolate_data->simulator();
953  if (sim == NULL) {
954    // TODO(146): delete the simulator object when a thread/isolate goes away.
955    sim = new Simulator(isolate);
956    isolate_data->set_simulator(sim);
957  }
958  return sim;
959}
960
961
962// Sets the register in the architecture state.
963void Simulator::set_register(int reg, intptr_t value) {
964  DCHECK((reg >= 0) && (reg < kNumGPRs));
965  registers_[reg] = value;
966}
967
968
969// Get the register from the architecture state.
970intptr_t Simulator::get_register(int reg) const {
971  DCHECK((reg >= 0) && (reg < kNumGPRs));
972  // Stupid code added to avoid bug in GCC.
973  // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
974  if (reg >= kNumGPRs) return 0;
975  // End stupid code.
976  return registers_[reg];
977}
978
979
980double Simulator::get_double_from_register_pair(int reg) {
981  DCHECK((reg >= 0) && (reg < kNumGPRs) && ((reg % 2) == 0));
982
983  double dm_val = 0.0;
984#if !V8_TARGET_ARCH_PPC64  // doesn't make sense in 64bit mode
985  // Read the bits from the unsigned integer register_[] array
986  // into the double precision floating point value and return it.
987  char buffer[sizeof(fp_registers_[0])];
988  memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
989  memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
990#endif
991  return (dm_val);
992}
993
994
995// Raw access to the PC register.
996void Simulator::set_pc(intptr_t value) {
997  pc_modified_ = true;
998  special_reg_pc_ = value;
999}
1000
1001
1002bool Simulator::has_bad_pc() const {
1003  return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc));
1004}
1005
1006
1007// Raw access to the PC register without the special adjustment when reading.
1008intptr_t Simulator::get_pc() const { return special_reg_pc_; }
1009
1010
1011// Runtime FP routines take:
1012// - two double arguments
1013// - one double argument and zero or one integer arguments.
1014// All are consructed here from d1, d2 and r3.
1015void Simulator::GetFpArgs(double* x, double* y, intptr_t* z) {
1016  *x = get_double_from_d_register(1);
1017  *y = get_double_from_d_register(2);
1018  *z = get_register(3);
1019}
1020
1021
1022// The return value is in d1.
1023void Simulator::SetFpResult(const double& result) {
1024  set_d_register_from_double(1, result);
1025}
1026
1027
1028void Simulator::TrashCallerSaveRegisters() {
1029// We don't trash the registers with the return value.
1030#if 0  // A good idea to trash volatile registers, needs to be done
1031  registers_[2] = 0x50Bad4U;
1032  registers_[3] = 0x50Bad4U;
1033  registers_[12] = 0x50Bad4U;
1034#endif
1035}
1036
1037
1038uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) {
1039  uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
1040  return *ptr;
1041}
1042
1043
1044int32_t Simulator::ReadW(intptr_t addr, Instruction* instr) {
1045  int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1046  return *ptr;
1047}
1048
1049
1050void Simulator::WriteW(intptr_t addr, uint32_t value, Instruction* instr) {
1051  uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
1052  *ptr = value;
1053  return;
1054}
1055
1056
1057void Simulator::WriteW(intptr_t addr, int32_t value, Instruction* instr) {
1058  int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1059  *ptr = value;
1060  return;
1061}
1062
1063
1064uint16_t Simulator::ReadHU(intptr_t addr, Instruction* instr) {
1065  uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1066  return *ptr;
1067}
1068
1069
1070int16_t Simulator::ReadH(intptr_t addr, Instruction* instr) {
1071  int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1072  return *ptr;
1073}
1074
1075
1076void Simulator::WriteH(intptr_t addr, uint16_t value, Instruction* instr) {
1077  uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1078  *ptr = value;
1079  return;
1080}
1081
1082
1083void Simulator::WriteH(intptr_t addr, int16_t value, Instruction* instr) {
1084  int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1085  *ptr = value;
1086  return;
1087}
1088
1089
1090uint8_t Simulator::ReadBU(intptr_t addr) {
1091  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1092  return *ptr;
1093}
1094
1095
1096int8_t Simulator::ReadB(intptr_t addr) {
1097  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1098  return *ptr;
1099}
1100
1101
1102void Simulator::WriteB(intptr_t addr, uint8_t value) {
1103  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1104  *ptr = value;
1105}
1106
1107
1108void Simulator::WriteB(intptr_t addr, int8_t value) {
1109  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1110  *ptr = value;
1111}
1112
1113
1114intptr_t* Simulator::ReadDW(intptr_t addr) {
1115  intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1116  return ptr;
1117}
1118
1119
1120void Simulator::WriteDW(intptr_t addr, int64_t value) {
1121  int64_t* ptr = reinterpret_cast<int64_t*>(addr);
1122  *ptr = value;
1123  return;
1124}
1125
1126
1127// Returns the limit of the stack area to enable checking for stack overflows.
1128uintptr_t Simulator::StackLimit(uintptr_t c_limit) const {
1129  // The simulator uses a separate JS stack. If we have exhausted the C stack,
1130  // we also drop down the JS limit to reflect the exhaustion on the JS stack.
1131  if (GetCurrentStackPosition() < c_limit) {
1132    return reinterpret_cast<uintptr_t>(get_sp());
1133  }
1134
1135  // Otherwise the limit is the JS stack. Leave a safety margin to prevent
1136  // overrunning the stack when pushing values.
1137  return reinterpret_cast<uintptr_t>(stack_) + stack_protection_size_;
1138}
1139
1140
1141// Unsupported instructions use Format to print an error and stop execution.
1142void Simulator::Format(Instruction* instr, const char* format) {
1143  PrintF("Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR ": %s\n",
1144         reinterpret_cast<intptr_t>(instr), format);
1145  UNIMPLEMENTED();
1146}
1147
1148
1149// Calculate C flag value for additions.
1150bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
1151  uint32_t uleft = static_cast<uint32_t>(left);
1152  uint32_t uright = static_cast<uint32_t>(right);
1153  uint32_t urest = 0xffffffffU - uleft;
1154
1155  return (uright > urest) ||
1156         (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
1157}
1158
1159
1160// Calculate C flag value for subtractions.
1161bool Simulator::BorrowFrom(int32_t left, int32_t right) {
1162  uint32_t uleft = static_cast<uint32_t>(left);
1163  uint32_t uright = static_cast<uint32_t>(right);
1164
1165  return (uright > uleft);
1166}
1167
1168
1169// Calculate V flag value for additions and subtractions.
1170bool Simulator::OverflowFrom(int32_t alu_out, int32_t left, int32_t right,
1171                             bool addition) {
1172  bool overflow;
1173  if (addition) {
1174    // operands have the same sign
1175    overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
1176               // and operands and result have different sign
1177               &&
1178               ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1179  } else {
1180    // operands have different signs
1181    overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
1182               // and first operand and result have different signs
1183               &&
1184               ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1185  }
1186  return overflow;
1187}
1188
1189
1190#if V8_TARGET_ARCH_PPC64
1191static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
1192  *x = reinterpret_cast<intptr_t>(pair->x);
1193  *y = reinterpret_cast<intptr_t>(pair->y);
1194}
1195#else
1196static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
1197#if V8_TARGET_BIG_ENDIAN
1198  *x = static_cast<int32_t>(*pair >> 32);
1199  *y = static_cast<int32_t>(*pair);
1200#else
1201  *x = static_cast<int32_t>(*pair);
1202  *y = static_cast<int32_t>(*pair >> 32);
1203#endif
1204}
1205#endif
1206
1207// Calls into the V8 runtime.
1208typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
1209                                         intptr_t arg2, intptr_t arg3,
1210                                         intptr_t arg4, intptr_t arg5);
1211typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1,
1212                                               intptr_t arg2, intptr_t arg3,
1213                                               intptr_t arg4, intptr_t arg5);
1214typedef ObjectTriple (*SimulatorRuntimeTripleCall)(intptr_t arg0, intptr_t arg1,
1215                                                   intptr_t arg2, intptr_t arg3,
1216                                                   intptr_t arg4,
1217                                                   intptr_t arg5);
1218
1219// These prototypes handle the four types of FP calls.
1220typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
1221typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
1222typedef double (*SimulatorRuntimeFPCall)(double darg0);
1223typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0);
1224
1225// This signature supports direct call in to API function native callback
1226// (refer to InvocationCallback in v8.h).
1227typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0);
1228typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1);
1229
1230// This signature supports direct call to accessor getter callback.
1231typedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1);
1232typedef void (*SimulatorRuntimeProfilingGetterCall)(intptr_t arg0,
1233                                                    intptr_t arg1, void* arg2);
1234
1235// Software interrupt instructions are used by the simulator to call into the
1236// C-based V8 runtime.
1237void Simulator::SoftwareInterrupt(Instruction* instr) {
1238  int svc = instr->SvcValue();
1239  switch (svc) {
1240    case kCallRtRedirected: {
1241      // Check if stack is aligned. Error if not aligned is reported below to
1242      // include information on the function called.
1243      bool stack_aligned =
1244          (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) ==
1245          0;
1246      Redirection* redirection = Redirection::FromSwiInstruction(instr);
1247      const int kArgCount = 6;
1248      int arg0_regnum = 3;
1249      intptr_t result_buffer = 0;
1250      bool uses_result_buffer =
1251          redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE ||
1252          (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR &&
1253           !ABI_RETURNS_OBJECT_PAIRS_IN_REGS);
1254      if (uses_result_buffer) {
1255        result_buffer = get_register(r3);
1256        arg0_regnum++;
1257      }
1258      intptr_t arg[kArgCount];
1259      for (int i = 0; i < kArgCount; i++) {
1260        arg[i] = get_register(arg0_regnum + i);
1261      }
1262      bool fp_call =
1263          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1264          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1265          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1266          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1267      // This is dodgy but it works because the C entry stubs are never moved.
1268      // See comment in codegen-arm.cc and bug 1242173.
1269      intptr_t saved_lr = special_reg_lr_;
1270      intptr_t external =
1271          reinterpret_cast<intptr_t>(redirection->external_function());
1272      if (fp_call) {
1273        double dval0, dval1;  // one or two double parameters
1274        intptr_t ival;        // zero or one integer parameters
1275        int iresult = 0;      // integer return value
1276        double dresult = 0;   // double return value
1277        GetFpArgs(&dval0, &dval1, &ival);
1278        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1279          SimulatorRuntimeCall generic_target =
1280              reinterpret_cast<SimulatorRuntimeCall>(external);
1281          switch (redirection->type()) {
1282            case ExternalReference::BUILTIN_FP_FP_CALL:
1283            case ExternalReference::BUILTIN_COMPARE_CALL:
1284              PrintF("Call to host function at %p with args %f, %f",
1285                     static_cast<void*>(FUNCTION_ADDR(generic_target)),
1286                     dval0, dval1);
1287              break;
1288            case ExternalReference::BUILTIN_FP_CALL:
1289              PrintF("Call to host function at %p with arg %f",
1290                     static_cast<void*>(FUNCTION_ADDR(generic_target)),
1291                     dval0);
1292              break;
1293            case ExternalReference::BUILTIN_FP_INT_CALL:
1294              PrintF("Call to host function at %p with args %f, %" V8PRIdPTR,
1295                     static_cast<void*>(FUNCTION_ADDR(generic_target)),
1296                     dval0, ival);
1297              break;
1298            default:
1299              UNREACHABLE();
1300              break;
1301          }
1302          if (!stack_aligned) {
1303            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
1304                   get_register(sp));
1305          }
1306          PrintF("\n");
1307        }
1308        CHECK(stack_aligned);
1309        switch (redirection->type()) {
1310          case ExternalReference::BUILTIN_COMPARE_CALL: {
1311            SimulatorRuntimeCompareCall target =
1312                reinterpret_cast<SimulatorRuntimeCompareCall>(external);
1313            iresult = target(dval0, dval1);
1314            set_register(r3, iresult);
1315            break;
1316          }
1317          case ExternalReference::BUILTIN_FP_FP_CALL: {
1318            SimulatorRuntimeFPFPCall target =
1319                reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
1320            dresult = target(dval0, dval1);
1321            SetFpResult(dresult);
1322            break;
1323          }
1324          case ExternalReference::BUILTIN_FP_CALL: {
1325            SimulatorRuntimeFPCall target =
1326                reinterpret_cast<SimulatorRuntimeFPCall>(external);
1327            dresult = target(dval0);
1328            SetFpResult(dresult);
1329            break;
1330          }
1331          case ExternalReference::BUILTIN_FP_INT_CALL: {
1332            SimulatorRuntimeFPIntCall target =
1333                reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
1334            dresult = target(dval0, ival);
1335            SetFpResult(dresult);
1336            break;
1337          }
1338          default:
1339            UNREACHABLE();
1340            break;
1341        }
1342        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1343          switch (redirection->type()) {
1344            case ExternalReference::BUILTIN_COMPARE_CALL:
1345              PrintF("Returned %08x\n", iresult);
1346              break;
1347            case ExternalReference::BUILTIN_FP_FP_CALL:
1348            case ExternalReference::BUILTIN_FP_CALL:
1349            case ExternalReference::BUILTIN_FP_INT_CALL:
1350              PrintF("Returned %f\n", dresult);
1351              break;
1352            default:
1353              UNREACHABLE();
1354              break;
1355          }
1356        }
1357      } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1358        // See callers of MacroAssembler::CallApiFunctionAndReturn for
1359        // explanation of register usage.
1360        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1361          PrintF("Call to host function at %p args %08" V8PRIxPTR,
1362                 reinterpret_cast<void*>(external), arg[0]);
1363          if (!stack_aligned) {
1364            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
1365                   get_register(sp));
1366          }
1367          PrintF("\n");
1368        }
1369        CHECK(stack_aligned);
1370        SimulatorRuntimeDirectApiCall target =
1371            reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
1372        target(arg[0]);
1373      } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
1374        // See callers of MacroAssembler::CallApiFunctionAndReturn for
1375        // explanation of register usage.
1376        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1377          PrintF("Call to host function at %p args %08" V8PRIxPTR
1378                 " %08" V8PRIxPTR,
1379                 reinterpret_cast<void*>(external), arg[0], arg[1]);
1380          if (!stack_aligned) {
1381            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
1382                   get_register(sp));
1383          }
1384          PrintF("\n");
1385        }
1386        CHECK(stack_aligned);
1387        SimulatorRuntimeProfilingApiCall target =
1388            reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
1389        target(arg[0], Redirection::ReverseRedirection(arg[1]));
1390      } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
1391        // See callers of MacroAssembler::CallApiFunctionAndReturn for
1392        // explanation of register usage.
1393        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1394          PrintF("Call to host function at %p args %08" V8PRIxPTR
1395                 " %08" V8PRIxPTR,
1396                 reinterpret_cast<void*>(external), arg[0], arg[1]);
1397          if (!stack_aligned) {
1398            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
1399                   get_register(sp));
1400          }
1401          PrintF("\n");
1402        }
1403        CHECK(stack_aligned);
1404        SimulatorRuntimeDirectGetterCall target =
1405            reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
1406        if (!ABI_PASSES_HANDLES_IN_REGS) {
1407          arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
1408        }
1409        target(arg[0], arg[1]);
1410      } else if (redirection->type() ==
1411                 ExternalReference::PROFILING_GETTER_CALL) {
1412        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1413          PrintF("Call to host function at %p args %08" V8PRIxPTR
1414                 " %08" V8PRIxPTR " %08" V8PRIxPTR,
1415                 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]);
1416          if (!stack_aligned) {
1417            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
1418                   get_register(sp));
1419          }
1420          PrintF("\n");
1421        }
1422        CHECK(stack_aligned);
1423        SimulatorRuntimeProfilingGetterCall target =
1424            reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
1425        if (!ABI_PASSES_HANDLES_IN_REGS) {
1426          arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
1427        }
1428        target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
1429      } else {
1430        // builtin call.
1431        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1432          SimulatorRuntimeCall target =
1433              reinterpret_cast<SimulatorRuntimeCall>(external);
1434          PrintF(
1435              "Call to host function at %p,\n"
1436              "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
1437              ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR,
1438              static_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1],
1439              arg[2], arg[3], arg[4], arg[5]);
1440          if (!stack_aligned) {
1441            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
1442                   get_register(sp));
1443          }
1444          PrintF("\n");
1445        }
1446        CHECK(stack_aligned);
1447        if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE) {
1448          SimulatorRuntimeTripleCall target =
1449              reinterpret_cast<SimulatorRuntimeTripleCall>(external);
1450          ObjectTriple result =
1451              target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
1452          if (::v8::internal::FLAG_trace_sim) {
1453            PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
1454                   "}\n",
1455                   reinterpret_cast<intptr_t>(result.x),
1456                   reinterpret_cast<intptr_t>(result.y),
1457                   reinterpret_cast<intptr_t>(result.z));
1458          }
1459          memcpy(reinterpret_cast<void*>(result_buffer), &result,
1460                 sizeof(ObjectTriple));
1461          set_register(r3, result_buffer);
1462        } else {
1463          if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) {
1464            SimulatorRuntimePairCall target =
1465                reinterpret_cast<SimulatorRuntimePairCall>(external);
1466            ObjectPair result =
1467                target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
1468            intptr_t x;
1469            intptr_t y;
1470            decodeObjectPair(&result, &x, &y);
1471            if (::v8::internal::FLAG_trace_sim) {
1472              PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y);
1473            }
1474            if (ABI_RETURNS_OBJECT_PAIRS_IN_REGS) {
1475              set_register(r3, x);
1476              set_register(r4, y);
1477            } else {
1478              memcpy(reinterpret_cast<void*>(result_buffer), &result,
1479                     sizeof(ObjectPair));
1480              set_register(r3, result_buffer);
1481            }
1482          } else {
1483            DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL);
1484            SimulatorRuntimeCall target =
1485                reinterpret_cast<SimulatorRuntimeCall>(external);
1486            intptr_t result =
1487                target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
1488            if (::v8::internal::FLAG_trace_sim) {
1489              PrintF("Returned %08" V8PRIxPTR "\n", result);
1490            }
1491            set_register(r3, result);
1492          }
1493        }
1494      }
1495      set_pc(saved_lr);
1496      break;
1497    }
1498    case kBreakpoint: {
1499      PPCDebugger dbg(this);
1500      dbg.Debug();
1501      break;
1502    }
1503    // stop uses all codes greater than 1 << 23.
1504    default: {
1505      if (svc >= (1 << 23)) {
1506        uint32_t code = svc & kStopCodeMask;
1507        if (isWatchedStop(code)) {
1508          IncreaseStopCounter(code);
1509        }
1510        // Stop if it is enabled, otherwise go on jumping over the stop
1511        // and the message address.
1512        if (isEnabledStop(code)) {
1513          PPCDebugger dbg(this);
1514          dbg.Stop(instr);
1515        } else {
1516          set_pc(get_pc() + Instruction::kInstrSize + kPointerSize);
1517        }
1518      } else {
1519        // This is not a valid svc code.
1520        UNREACHABLE();
1521        break;
1522      }
1523    }
1524  }
1525}
1526
1527
1528// Stop helper functions.
1529bool Simulator::isStopInstruction(Instruction* instr) {
1530  return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
1531}
1532
1533
1534bool Simulator::isWatchedStop(uint32_t code) {
1535  DCHECK(code <= kMaxStopCode);
1536  return code < kNumOfWatchedStops;
1537}
1538
1539
1540bool Simulator::isEnabledStop(uint32_t code) {
1541  DCHECK(code <= kMaxStopCode);
1542  // Unwatched stops are always enabled.
1543  return !isWatchedStop(code) ||
1544         !(watched_stops_[code].count & kStopDisabledBit);
1545}
1546
1547
1548void Simulator::EnableStop(uint32_t code) {
1549  DCHECK(isWatchedStop(code));
1550  if (!isEnabledStop(code)) {
1551    watched_stops_[code].count &= ~kStopDisabledBit;
1552  }
1553}
1554
1555
1556void Simulator::DisableStop(uint32_t code) {
1557  DCHECK(isWatchedStop(code));
1558  if (isEnabledStop(code)) {
1559    watched_stops_[code].count |= kStopDisabledBit;
1560  }
1561}
1562
1563
1564void Simulator::IncreaseStopCounter(uint32_t code) {
1565  DCHECK(code <= kMaxStopCode);
1566  DCHECK(isWatchedStop(code));
1567  if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
1568    PrintF(
1569        "Stop counter for code %i has overflowed.\n"
1570        "Enabling this code and reseting the counter to 0.\n",
1571        code);
1572    watched_stops_[code].count = 0;
1573    EnableStop(code);
1574  } else {
1575    watched_stops_[code].count++;
1576  }
1577}
1578
1579
1580// Print a stop status.
1581void Simulator::PrintStopInfo(uint32_t code) {
1582  DCHECK(code <= kMaxStopCode);
1583  if (!isWatchedStop(code)) {
1584    PrintF("Stop not watched.");
1585  } else {
1586    const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
1587    int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
1588    // Don't print the state of unused breakpoints.
1589    if (count != 0) {
1590      if (watched_stops_[code].desc) {
1591        PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code,
1592               state, count, watched_stops_[code].desc);
1593      } else {
1594        PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state,
1595               count);
1596      }
1597    }
1598  }
1599}
1600
1601
1602void Simulator::SetCR0(intptr_t result, bool setSO) {
1603  int bf = 0;
1604  if (result < 0) {
1605    bf |= 0x80000000;
1606  }
1607  if (result > 0) {
1608    bf |= 0x40000000;
1609  }
1610  if (result == 0) {
1611    bf |= 0x20000000;
1612  }
1613  if (setSO) {
1614    bf |= 0x10000000;
1615  }
1616  condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
1617}
1618
1619
1620void Simulator::ExecuteBranchConditional(Instruction* instr, BCType type) {
1621  int bo = instr->Bits(25, 21) << 21;
1622  int condition_bit = instr->Bits(20, 16);
1623  int condition_mask = 0x80000000 >> condition_bit;
1624  switch (bo) {
1625    case DCBNZF:  // Decrement CTR; branch if CTR != 0 and condition false
1626    case DCBEZF:  // Decrement CTR; branch if CTR == 0 and condition false
1627      UNIMPLEMENTED();
1628    case BF: {  // Branch if condition false
1629      if (condition_reg_ & condition_mask) return;
1630      break;
1631    }
1632    case DCBNZT:  // Decrement CTR; branch if CTR != 0 and condition true
1633    case DCBEZT:  // Decrement CTR; branch if CTR == 0 and condition true
1634      UNIMPLEMENTED();
1635    case BT: {  // Branch if condition true
1636      if (!(condition_reg_ & condition_mask)) return;
1637      break;
1638    }
1639    case DCBNZ:  // Decrement CTR; branch if CTR != 0
1640    case DCBEZ:  // Decrement CTR; branch if CTR == 0
1641      special_reg_ctr_ -= 1;
1642      if ((special_reg_ctr_ == 0) != (bo == DCBEZ)) return;
1643      break;
1644    case BA: {                   // Branch always
1645      break;
1646    }
1647    default:
1648      UNIMPLEMENTED();  // Invalid encoding
1649  }
1650
1651  intptr_t old_pc = get_pc();
1652
1653  switch (type) {
1654    case BC_OFFSET: {
1655      int offset = (instr->Bits(15, 2) << 18) >> 16;
1656      set_pc(old_pc + offset);
1657      break;
1658    }
1659    case BC_LINK_REG:
1660      set_pc(special_reg_lr_);
1661      break;
1662    case BC_CTR_REG:
1663      set_pc(special_reg_ctr_);
1664      break;
1665  }
1666
1667  if (instr->Bit(0) == 1) {  // LK flag set
1668    special_reg_lr_ = old_pc + 4;
1669  }
1670}
1671
1672
1673// Handle execution based on instruction types.
1674void Simulator::ExecuteExt1(Instruction* instr) {
1675  switch (instr->Bits(10, 1) << 1) {
1676    case MCRF:
1677      UNIMPLEMENTED();  // Not used by V8.
1678    case BCLRX:
1679      ExecuteBranchConditional(instr, BC_LINK_REG);
1680      break;
1681    case BCCTRX:
1682      ExecuteBranchConditional(instr, BC_CTR_REG);
1683      break;
1684    case CRNOR:
1685    case RFI:
1686    case CRANDC:
1687      UNIMPLEMENTED();
1688    case ISYNC: {
1689      // todo - simulate isync
1690      break;
1691    }
1692    case CRXOR: {
1693      int bt = instr->Bits(25, 21);
1694      int ba = instr->Bits(20, 16);
1695      int bb = instr->Bits(15, 11);
1696      int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
1697      int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
1698      int bt_val = ba_val ^ bb_val;
1699      bt_val = bt_val << (31 - bt);  // shift bit to correct destination
1700      condition_reg_ &= ~(0x80000000 >> bt);
1701      condition_reg_ |= bt_val;
1702      break;
1703    }
1704    case CREQV: {
1705      int bt = instr->Bits(25, 21);
1706      int ba = instr->Bits(20, 16);
1707      int bb = instr->Bits(15, 11);
1708      int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
1709      int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
1710      int bt_val = 1 - (ba_val ^ bb_val);
1711      bt_val = bt_val << (31 - bt);  // shift bit to correct destination
1712      condition_reg_ &= ~(0x80000000 >> bt);
1713      condition_reg_ |= bt_val;
1714      break;
1715    }
1716    case CRNAND:
1717    case CRAND:
1718    case CRORC:
1719    case CROR:
1720    default: {
1721      UNIMPLEMENTED();  // Not used by V8.
1722    }
1723  }
1724}
1725
1726
1727bool Simulator::ExecuteExt2_10bit(Instruction* instr) {
1728  bool found = true;
1729
1730  int opcode = instr->Bits(10, 1) << 1;
1731  switch (opcode) {
1732    case SRWX: {
1733      int rs = instr->RSValue();
1734      int ra = instr->RAValue();
1735      int rb = instr->RBValue();
1736      uint32_t rs_val = get_register(rs);
1737      uintptr_t rb_val = get_register(rb) & 0x3f;
1738      intptr_t result = (rb_val > 31) ? 0 : rs_val >> rb_val;
1739      set_register(ra, result);
1740      if (instr->Bit(0)) {  // RC bit set
1741        SetCR0(result);
1742      }
1743      break;
1744    }
1745#if V8_TARGET_ARCH_PPC64
1746    case SRDX: {
1747      int rs = instr->RSValue();
1748      int ra = instr->RAValue();
1749      int rb = instr->RBValue();
1750      uintptr_t rs_val = get_register(rs);
1751      uintptr_t rb_val = get_register(rb) & 0x7f;
1752      intptr_t result = (rb_val > 63) ? 0 : rs_val >> rb_val;
1753      set_register(ra, result);
1754      if (instr->Bit(0)) {  // RC bit set
1755        SetCR0(result);
1756      }
1757      break;
1758    }
1759#endif
1760    case SRAW: {
1761      int rs = instr->RSValue();
1762      int ra = instr->RAValue();
1763      int rb = instr->RBValue();
1764      int32_t rs_val = get_register(rs);
1765      intptr_t rb_val = get_register(rb) & 0x3f;
1766      intptr_t result = (rb_val > 31) ? rs_val >> 31 : rs_val >> rb_val;
1767      set_register(ra, result);
1768      if (instr->Bit(0)) {  // RC bit set
1769        SetCR0(result);
1770      }
1771      break;
1772    }
1773#if V8_TARGET_ARCH_PPC64
1774    case SRAD: {
1775      int rs = instr->RSValue();
1776      int ra = instr->RAValue();
1777      int rb = instr->RBValue();
1778      intptr_t rs_val = get_register(rs);
1779      intptr_t rb_val = get_register(rb) & 0x7f;
1780      intptr_t result = (rb_val > 63) ? rs_val >> 63 : rs_val >> rb_val;
1781      set_register(ra, result);
1782      if (instr->Bit(0)) {  // RC bit set
1783        SetCR0(result);
1784      }
1785      break;
1786    }
1787#endif
1788    case SRAWIX: {
1789      int ra = instr->RAValue();
1790      int rs = instr->RSValue();
1791      int sh = instr->Bits(15, 11);
1792      int32_t rs_val = get_register(rs);
1793      intptr_t result = rs_val >> sh;
1794      set_register(ra, result);
1795      if (instr->Bit(0)) {  // RC bit set
1796        SetCR0(result);
1797      }
1798      break;
1799    }
1800#if V8_TARGET_ARCH_PPC64
1801    case EXTSW: {
1802      const int shift = kBitsPerPointer - 32;
1803      int ra = instr->RAValue();
1804      int rs = instr->RSValue();
1805      intptr_t rs_val = get_register(rs);
1806      intptr_t ra_val = (rs_val << shift) >> shift;
1807      set_register(ra, ra_val);
1808      if (instr->Bit(0)) {  // RC bit set
1809        SetCR0(ra_val);
1810      }
1811      break;
1812    }
1813#endif
1814    case EXTSH: {
1815      const int shift = kBitsPerPointer - 16;
1816      int ra = instr->RAValue();
1817      int rs = instr->RSValue();
1818      intptr_t rs_val = get_register(rs);
1819      intptr_t ra_val = (rs_val << shift) >> shift;
1820      set_register(ra, ra_val);
1821      if (instr->Bit(0)) {  // RC bit set
1822        SetCR0(ra_val);
1823      }
1824      break;
1825    }
1826    case EXTSB: {
1827      const int shift = kBitsPerPointer - 8;
1828      int ra = instr->RAValue();
1829      int rs = instr->RSValue();
1830      intptr_t rs_val = get_register(rs);
1831      intptr_t ra_val = (rs_val << shift) >> shift;
1832      set_register(ra, ra_val);
1833      if (instr->Bit(0)) {  // RC bit set
1834        SetCR0(ra_val);
1835      }
1836      break;
1837    }
1838    case LFSUX:
1839    case LFSX: {
1840      int frt = instr->RTValue();
1841      int ra = instr->RAValue();
1842      int rb = instr->RBValue();
1843      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1844      intptr_t rb_val = get_register(rb);
1845      int32_t val = ReadW(ra_val + rb_val, instr);
1846      float* fptr = reinterpret_cast<float*>(&val);
1847      set_d_register_from_double(frt, static_cast<double>(*fptr));
1848      if (opcode == LFSUX) {
1849        DCHECK(ra != 0);
1850        set_register(ra, ra_val + rb_val);
1851      }
1852      break;
1853    }
1854    case LFDUX:
1855    case LFDX: {
1856      int frt = instr->RTValue();
1857      int ra = instr->RAValue();
1858      int rb = instr->RBValue();
1859      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1860      intptr_t rb_val = get_register(rb);
1861      int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + rb_val));
1862      set_d_register(frt, *dptr);
1863      if (opcode == LFDUX) {
1864        DCHECK(ra != 0);
1865        set_register(ra, ra_val + rb_val);
1866      }
1867      break;
1868    }
1869    case STFSUX: {
1870      case STFSX:
1871        int frs = instr->RSValue();
1872        int ra = instr->RAValue();
1873        int rb = instr->RBValue();
1874        intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1875        intptr_t rb_val = get_register(rb);
1876        float frs_val = static_cast<float>(get_double_from_d_register(frs));
1877        int32_t* p = reinterpret_cast<int32_t*>(&frs_val);
1878        WriteW(ra_val + rb_val, *p, instr);
1879        if (opcode == STFSUX) {
1880          DCHECK(ra != 0);
1881          set_register(ra, ra_val + rb_val);
1882        }
1883        break;
1884    }
1885    case STFDUX: {
1886      case STFDX:
1887        int frs = instr->RSValue();
1888        int ra = instr->RAValue();
1889        int rb = instr->RBValue();
1890        intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1891        intptr_t rb_val = get_register(rb);
1892        int64_t frs_val = get_d_register(frs);
1893        WriteDW(ra_val + rb_val, frs_val);
1894        if (opcode == STFDUX) {
1895          DCHECK(ra != 0);
1896          set_register(ra, ra_val + rb_val);
1897        }
1898        break;
1899    }
1900    case POPCNTW: {
1901      int rs = instr->RSValue();
1902      int ra = instr->RAValue();
1903      uintptr_t rs_val = get_register(rs);
1904      uintptr_t count = 0;
1905      int n = 0;
1906      uintptr_t bit = 0x80000000;
1907      for (; n < 32; n++) {
1908        if (bit & rs_val) count++;
1909        bit >>= 1;
1910      }
1911      set_register(ra, count);
1912      break;
1913    }
1914#if V8_TARGET_ARCH_PPC64
1915    case POPCNTD: {
1916      int rs = instr->RSValue();
1917      int ra = instr->RAValue();
1918      uintptr_t rs_val = get_register(rs);
1919      uintptr_t count = 0;
1920      int n = 0;
1921      uintptr_t bit = 0x8000000000000000UL;
1922      for (; n < 64; n++) {
1923        if (bit & rs_val) count++;
1924        bit >>= 1;
1925      }
1926      set_register(ra, count);
1927      break;
1928    }
1929#endif
1930    case SYNC: {
1931      // todo - simulate sync
1932      break;
1933    }
1934    case ICBI: {
1935      // todo - simulate icbi
1936      break;
1937    }
1938    default: {
1939      found = false;
1940      break;
1941    }
1942  }
1943
1944  if (found) return found;
1945
1946  found = true;
1947  opcode = instr->Bits(10, 2) << 2;
1948  switch (opcode) {
1949    case SRADIX: {
1950      int ra = instr->RAValue();
1951      int rs = instr->RSValue();
1952      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
1953      intptr_t rs_val = get_register(rs);
1954      intptr_t result = rs_val >> sh;
1955      set_register(ra, result);
1956      if (instr->Bit(0)) {  // RC bit set
1957        SetCR0(result);
1958      }
1959      break;
1960    }
1961    default: {
1962      found = false;
1963      break;
1964    }
1965  }
1966
1967  return found;
1968}
1969
1970
1971bool Simulator::ExecuteExt2_9bit_part1(Instruction* instr) {
1972  bool found = true;
1973
1974  int opcode = instr->Bits(9, 1) << 1;
1975  switch (opcode) {
1976    case TW: {
1977      // used for call redirection in simulation mode
1978      SoftwareInterrupt(instr);
1979      break;
1980    }
1981    case CMP: {
1982      int ra = instr->RAValue();
1983      int rb = instr->RBValue();
1984      int cr = instr->Bits(25, 23);
1985      uint32_t bf = 0;
1986#if V8_TARGET_ARCH_PPC64
1987      int L = instr->Bit(21);
1988      if (L) {
1989#endif
1990        intptr_t ra_val = get_register(ra);
1991        intptr_t rb_val = get_register(rb);
1992        if (ra_val < rb_val) {
1993          bf |= 0x80000000;
1994        }
1995        if (ra_val > rb_val) {
1996          bf |= 0x40000000;
1997        }
1998        if (ra_val == rb_val) {
1999          bf |= 0x20000000;
2000        }
2001#if V8_TARGET_ARCH_PPC64
2002      } else {
2003        int32_t ra_val = get_register(ra);
2004        int32_t rb_val = get_register(rb);
2005        if (ra_val < rb_val) {
2006          bf |= 0x80000000;
2007        }
2008        if (ra_val > rb_val) {
2009          bf |= 0x40000000;
2010        }
2011        if (ra_val == rb_val) {
2012          bf |= 0x20000000;
2013        }
2014      }
2015#endif
2016      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
2017      uint32_t condition = bf >> (cr * 4);
2018      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
2019      break;
2020    }
2021    case SUBFCX: {
2022      int rt = instr->RTValue();
2023      int ra = instr->RAValue();
2024      int rb = instr->RBValue();
2025      // int oe = instr->Bit(10);
2026      uintptr_t ra_val = get_register(ra);
2027      uintptr_t rb_val = get_register(rb);
2028      uintptr_t alu_out = ~ra_val + rb_val + 1;
2029      // Set carry
2030      if (ra_val <= rb_val) {
2031        special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
2032      } else {
2033        special_reg_xer_ &= ~0xF0000000;
2034      }
2035      set_register(rt, alu_out);
2036      if (instr->Bit(0)) {  // RC bit set
2037        SetCR0(alu_out);
2038      }
2039      // todo - handle OE bit
2040      break;
2041    }
2042    case SUBFEX: {
2043      int rt = instr->RTValue();
2044      int ra = instr->RAValue();
2045      int rb = instr->RBValue();
2046      // int oe = instr->Bit(10);
2047      uintptr_t ra_val = get_register(ra);
2048      uintptr_t rb_val = get_register(rb);
2049      uintptr_t alu_out = ~ra_val + rb_val;
2050      if (special_reg_xer_ & 0x20000000) {
2051        alu_out += 1;
2052      }
2053      set_register(rt, alu_out);
2054      if (instr->Bit(0)) {  // RC bit set
2055        SetCR0(static_cast<intptr_t>(alu_out));
2056      }
2057      // todo - handle OE bit
2058      break;
2059    }
2060    case ADDCX: {
2061      int rt = instr->RTValue();
2062      int ra = instr->RAValue();
2063      int rb = instr->RBValue();
2064      // int oe = instr->Bit(10);
2065      uintptr_t ra_val = get_register(ra);
2066      uintptr_t rb_val = get_register(rb);
2067      uintptr_t alu_out = ra_val + rb_val;
2068      // Set carry
2069      if (~ra_val < rb_val) {
2070        special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
2071      } else {
2072        special_reg_xer_ &= ~0xF0000000;
2073      }
2074      set_register(rt, alu_out);
2075      if (instr->Bit(0)) {  // RC bit set
2076        SetCR0(static_cast<intptr_t>(alu_out));
2077      }
2078      // todo - handle OE bit
2079      break;
2080    }
2081    case ADDEX: {
2082      int rt = instr->RTValue();
2083      int ra = instr->RAValue();
2084      int rb = instr->RBValue();
2085      // int oe = instr->Bit(10);
2086      uintptr_t ra_val = get_register(ra);
2087      uintptr_t rb_val = get_register(rb);
2088      uintptr_t alu_out = ra_val + rb_val;
2089      if (special_reg_xer_ & 0x20000000) {
2090        alu_out += 1;
2091      }
2092      set_register(rt, alu_out);
2093      if (instr->Bit(0)) {  // RC bit set
2094        SetCR0(static_cast<intptr_t>(alu_out));
2095      }
2096      // todo - handle OE bit
2097      break;
2098    }
2099    case MULHWX: {
2100      int rt = instr->RTValue();
2101      int ra = instr->RAValue();
2102      int rb = instr->RBValue();
2103      int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2104      int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2105      int64_t alu_out = (int64_t)ra_val * (int64_t)rb_val;
2106      alu_out >>= 32;
2107      set_register(rt, alu_out);
2108      if (instr->Bit(0)) {  // RC bit set
2109        SetCR0(static_cast<intptr_t>(alu_out));
2110      }
2111      break;
2112    }
2113    case MULHWUX: {
2114      int rt = instr->RTValue();
2115      int ra = instr->RAValue();
2116      int rb = instr->RBValue();
2117      uint32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2118      uint32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2119      uint64_t alu_out = (uint64_t)ra_val * (uint64_t)rb_val;
2120      alu_out >>= 32;
2121      set_register(rt, alu_out);
2122      if (instr->Bit(0)) {  // RC bit set
2123        SetCR0(static_cast<intptr_t>(alu_out));
2124      }
2125      break;
2126    }
2127    case NEGX: {
2128      int rt = instr->RTValue();
2129      int ra = instr->RAValue();
2130      intptr_t ra_val = get_register(ra);
2131      intptr_t alu_out = 1 + ~ra_val;
2132#if V8_TARGET_ARCH_PPC64
2133      intptr_t one = 1;  // work-around gcc
2134      intptr_t kOverflowVal = (one << 63);
2135#else
2136      intptr_t kOverflowVal = kMinInt;
2137#endif
2138      set_register(rt, alu_out);
2139      if (instr->Bit(10)) {  // OE bit set
2140        if (ra_val == kOverflowVal) {
2141          special_reg_xer_ |= 0xC0000000;  // set SO,OV
2142        } else {
2143          special_reg_xer_ &= ~0x40000000;  // clear OV
2144        }
2145      }
2146      if (instr->Bit(0)) {  // RC bit set
2147        bool setSO = (special_reg_xer_ & 0x80000000);
2148        SetCR0(alu_out, setSO);
2149      }
2150      break;
2151    }
2152    case SLWX: {
2153      int rs = instr->RSValue();
2154      int ra = instr->RAValue();
2155      int rb = instr->RBValue();
2156      uint32_t rs_val = get_register(rs);
2157      uintptr_t rb_val = get_register(rb) & 0x3f;
2158      uint32_t result = (rb_val > 31) ? 0 : rs_val << rb_val;
2159      set_register(ra, result);
2160      if (instr->Bit(0)) {  // RC bit set
2161        SetCR0(result);
2162      }
2163      break;
2164    }
2165#if V8_TARGET_ARCH_PPC64
2166    case SLDX: {
2167      int rs = instr->RSValue();
2168      int ra = instr->RAValue();
2169      int rb = instr->RBValue();
2170      uintptr_t rs_val = get_register(rs);
2171      uintptr_t rb_val = get_register(rb) & 0x7f;
2172      uintptr_t result = (rb_val > 63) ? 0 : rs_val << rb_val;
2173      set_register(ra, result);
2174      if (instr->Bit(0)) {  // RC bit set
2175        SetCR0(result);
2176      }
2177      break;
2178    }
2179    case MFVSRD: {
2180      DCHECK(!instr->Bit(0));
2181      int frt = instr->RTValue();
2182      int ra = instr->RAValue();
2183      int64_t frt_val = get_d_register(frt);
2184      set_register(ra, frt_val);
2185      break;
2186    }
2187    case MFVSRWZ: {
2188      DCHECK(!instr->Bit(0));
2189      int frt = instr->RTValue();
2190      int ra = instr->RAValue();
2191      int64_t frt_val = get_d_register(frt);
2192      set_register(ra, static_cast<uint32_t>(frt_val));
2193      break;
2194    }
2195    case MTVSRD: {
2196      DCHECK(!instr->Bit(0));
2197      int frt = instr->RTValue();
2198      int ra = instr->RAValue();
2199      int64_t ra_val = get_register(ra);
2200      set_d_register(frt, ra_val);
2201      break;
2202    }
2203    case MTVSRWA: {
2204      DCHECK(!instr->Bit(0));
2205      int frt = instr->RTValue();
2206      int ra = instr->RAValue();
2207      int64_t ra_val = static_cast<int32_t>(get_register(ra));
2208      set_d_register(frt, ra_val);
2209      break;
2210    }
2211    case MTVSRWZ: {
2212      DCHECK(!instr->Bit(0));
2213      int frt = instr->RTValue();
2214      int ra = instr->RAValue();
2215      uint64_t ra_val = static_cast<uint32_t>(get_register(ra));
2216      set_d_register(frt, ra_val);
2217      break;
2218    }
2219#endif
2220    default: {
2221      found = false;
2222      break;
2223    }
2224  }
2225
2226  return found;
2227}
2228
2229
2230bool Simulator::ExecuteExt2_9bit_part2(Instruction* instr) {
2231  bool found = true;
2232  int opcode = instr->Bits(9, 1) << 1;
2233  switch (opcode) {
2234    case CNTLZWX: {
2235      int rs = instr->RSValue();
2236      int ra = instr->RAValue();
2237      uintptr_t rs_val = get_register(rs);
2238      uintptr_t count = 0;
2239      int n = 0;
2240      uintptr_t bit = 0x80000000;
2241      for (; n < 32; n++) {
2242        if (bit & rs_val) break;
2243        count++;
2244        bit >>= 1;
2245      }
2246      set_register(ra, count);
2247      if (instr->Bit(0)) {  // RC Bit set
2248        int bf = 0;
2249        if (count > 0) {
2250          bf |= 0x40000000;
2251        }
2252        if (count == 0) {
2253          bf |= 0x20000000;
2254        }
2255        condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2256      }
2257      break;
2258    }
2259#if V8_TARGET_ARCH_PPC64
2260    case CNTLZDX: {
2261      int rs = instr->RSValue();
2262      int ra = instr->RAValue();
2263      uintptr_t rs_val = get_register(rs);
2264      uintptr_t count = 0;
2265      int n = 0;
2266      uintptr_t bit = 0x8000000000000000UL;
2267      for (; n < 64; n++) {
2268        if (bit & rs_val) break;
2269        count++;
2270        bit >>= 1;
2271      }
2272      set_register(ra, count);
2273      if (instr->Bit(0)) {  // RC Bit set
2274        int bf = 0;
2275        if (count > 0) {
2276          bf |= 0x40000000;
2277        }
2278        if (count == 0) {
2279          bf |= 0x20000000;
2280        }
2281        condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2282      }
2283      break;
2284    }
2285#endif
2286    case ANDX: {
2287      int rs = instr->RSValue();
2288      int ra = instr->RAValue();
2289      int rb = instr->RBValue();
2290      intptr_t rs_val = get_register(rs);
2291      intptr_t rb_val = get_register(rb);
2292      intptr_t alu_out = rs_val & rb_val;
2293      set_register(ra, alu_out);
2294      if (instr->Bit(0)) {  // RC Bit set
2295        SetCR0(alu_out);
2296      }
2297      break;
2298    }
2299    case ANDCX: {
2300      int rs = instr->RSValue();
2301      int ra = instr->RAValue();
2302      int rb = instr->RBValue();
2303      intptr_t rs_val = get_register(rs);
2304      intptr_t rb_val = get_register(rb);
2305      intptr_t alu_out = rs_val & ~rb_val;
2306      set_register(ra, alu_out);
2307      if (instr->Bit(0)) {  // RC Bit set
2308        SetCR0(alu_out);
2309      }
2310      break;
2311    }
2312    case CMPL: {
2313      int ra = instr->RAValue();
2314      int rb = instr->RBValue();
2315      int cr = instr->Bits(25, 23);
2316      uint32_t bf = 0;
2317#if V8_TARGET_ARCH_PPC64
2318      int L = instr->Bit(21);
2319      if (L) {
2320#endif
2321        uintptr_t ra_val = get_register(ra);
2322        uintptr_t rb_val = get_register(rb);
2323        if (ra_val < rb_val) {
2324          bf |= 0x80000000;
2325        }
2326        if (ra_val > rb_val) {
2327          bf |= 0x40000000;
2328        }
2329        if (ra_val == rb_val) {
2330          bf |= 0x20000000;
2331        }
2332#if V8_TARGET_ARCH_PPC64
2333      } else {
2334        uint32_t ra_val = get_register(ra);
2335        uint32_t rb_val = get_register(rb);
2336        if (ra_val < rb_val) {
2337          bf |= 0x80000000;
2338        }
2339        if (ra_val > rb_val) {
2340          bf |= 0x40000000;
2341        }
2342        if (ra_val == rb_val) {
2343          bf |= 0x20000000;
2344        }
2345      }
2346#endif
2347      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
2348      uint32_t condition = bf >> (cr * 4);
2349      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
2350      break;
2351    }
2352    case SUBFX: {
2353      int rt = instr->RTValue();
2354      int ra = instr->RAValue();
2355      int rb = instr->RBValue();
2356      // int oe = instr->Bit(10);
2357      intptr_t ra_val = get_register(ra);
2358      intptr_t rb_val = get_register(rb);
2359      intptr_t alu_out = rb_val - ra_val;
2360      // todo - figure out underflow
2361      set_register(rt, alu_out);
2362      if (instr->Bit(0)) {  // RC Bit set
2363        SetCR0(alu_out);
2364      }
2365      // todo - handle OE bit
2366      break;
2367    }
2368    case ADDZEX: {
2369      int rt = instr->RTValue();
2370      int ra = instr->RAValue();
2371      intptr_t ra_val = get_register(ra);
2372      if (special_reg_xer_ & 0x20000000) {
2373        ra_val += 1;
2374      }
2375      set_register(rt, ra_val);
2376      if (instr->Bit(0)) {  // RC bit set
2377        SetCR0(ra_val);
2378      }
2379      // todo - handle OE bit
2380      break;
2381    }
2382    case NORX: {
2383      int rs = instr->RSValue();
2384      int ra = instr->RAValue();
2385      int rb = instr->RBValue();
2386      intptr_t rs_val = get_register(rs);
2387      intptr_t rb_val = get_register(rb);
2388      intptr_t alu_out = ~(rs_val | rb_val);
2389      set_register(ra, alu_out);
2390      if (instr->Bit(0)) {  // RC bit set
2391        SetCR0(alu_out);
2392      }
2393      break;
2394    }
2395    case MULLW: {
2396      int rt = instr->RTValue();
2397      int ra = instr->RAValue();
2398      int rb = instr->RBValue();
2399      int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2400      int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2401      int32_t alu_out = ra_val * rb_val;
2402      set_register(rt, alu_out);
2403      if (instr->Bit(0)) {  // RC bit set
2404        SetCR0(alu_out);
2405      }
2406      // todo - handle OE bit
2407      break;
2408    }
2409#if V8_TARGET_ARCH_PPC64
2410    case MULLD: {
2411      int rt = instr->RTValue();
2412      int ra = instr->RAValue();
2413      int rb = instr->RBValue();
2414      int64_t ra_val = get_register(ra);
2415      int64_t rb_val = get_register(rb);
2416      int64_t alu_out = ra_val * rb_val;
2417      set_register(rt, alu_out);
2418      if (instr->Bit(0)) {  // RC bit set
2419        SetCR0(alu_out);
2420      }
2421      // todo - handle OE bit
2422      break;
2423    }
2424#endif
2425    case DIVW: {
2426      int rt = instr->RTValue();
2427      int ra = instr->RAValue();
2428      int rb = instr->RBValue();
2429      int32_t ra_val = get_register(ra);
2430      int32_t rb_val = get_register(rb);
2431      bool overflow = (ra_val == kMinInt && rb_val == -1);
2432      // result is undefined if divisor is zero or if operation
2433      // is 0x80000000 / -1.
2434      int32_t alu_out = (rb_val == 0 || overflow) ? -1 : ra_val / rb_val;
2435      set_register(rt, alu_out);
2436      if (instr->Bit(10)) {  // OE bit set
2437        if (overflow) {
2438          special_reg_xer_ |= 0xC0000000;  // set SO,OV
2439        } else {
2440          special_reg_xer_ &= ~0x40000000;  // clear OV
2441        }
2442      }
2443      if (instr->Bit(0)) {  // RC bit set
2444        bool setSO = (special_reg_xer_ & 0x80000000);
2445        SetCR0(alu_out, setSO);
2446      }
2447      break;
2448    }
2449    case DIVWU: {
2450      int rt = instr->RTValue();
2451      int ra = instr->RAValue();
2452      int rb = instr->RBValue();
2453      uint32_t ra_val = get_register(ra);
2454      uint32_t rb_val = get_register(rb);
2455      bool overflow = (rb_val == 0);
2456      // result is undefined if divisor is zero
2457      uint32_t alu_out = (overflow) ? -1 : ra_val / rb_val;
2458      set_register(rt, alu_out);
2459      if (instr->Bit(10)) {  // OE bit set
2460        if (overflow) {
2461          special_reg_xer_ |= 0xC0000000;  // set SO,OV
2462        } else {
2463          special_reg_xer_ &= ~0x40000000;  // clear OV
2464        }
2465      }
2466      if (instr->Bit(0)) {  // RC bit set
2467        bool setSO = (special_reg_xer_ & 0x80000000);
2468        SetCR0(alu_out, setSO);
2469      }
2470      break;
2471    }
2472#if V8_TARGET_ARCH_PPC64
2473    case DIVD: {
2474      int rt = instr->RTValue();
2475      int ra = instr->RAValue();
2476      int rb = instr->RBValue();
2477      int64_t ra_val = get_register(ra);
2478      int64_t rb_val = get_register(rb);
2479      int64_t one = 1;  // work-around gcc
2480      int64_t kMinLongLong = (one << 63);
2481      // result is undefined if divisor is zero or if operation
2482      // is 0x80000000_00000000 / -1.
2483      int64_t alu_out =
2484          (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1))
2485              ? -1
2486              : ra_val / rb_val;
2487      set_register(rt, alu_out);
2488      if (instr->Bit(0)) {  // RC bit set
2489        SetCR0(alu_out);
2490      }
2491      // todo - handle OE bit
2492      break;
2493    }
2494    case DIVDU: {
2495      int rt = instr->RTValue();
2496      int ra = instr->RAValue();
2497      int rb = instr->RBValue();
2498      uint64_t ra_val = get_register(ra);
2499      uint64_t rb_val = get_register(rb);
2500      // result is undefined if divisor is zero
2501      uint64_t alu_out = (rb_val == 0) ? -1 : ra_val / rb_val;
2502      set_register(rt, alu_out);
2503      if (instr->Bit(0)) {  // RC bit set
2504        SetCR0(alu_out);
2505      }
2506      // todo - handle OE bit
2507      break;
2508    }
2509#endif
2510    case ADDX: {
2511      int rt = instr->RTValue();
2512      int ra = instr->RAValue();
2513      int rb = instr->RBValue();
2514      // int oe = instr->Bit(10);
2515      intptr_t ra_val = get_register(ra);
2516      intptr_t rb_val = get_register(rb);
2517      intptr_t alu_out = ra_val + rb_val;
2518      set_register(rt, alu_out);
2519      if (instr->Bit(0)) {  // RC bit set
2520        SetCR0(alu_out);
2521      }
2522      // todo - handle OE bit
2523      break;
2524    }
2525    case XORX: {
2526      int rs = instr->RSValue();
2527      int ra = instr->RAValue();
2528      int rb = instr->RBValue();
2529      intptr_t rs_val = get_register(rs);
2530      intptr_t rb_val = get_register(rb);
2531      intptr_t alu_out = rs_val ^ rb_val;
2532      set_register(ra, alu_out);
2533      if (instr->Bit(0)) {  // RC bit set
2534        SetCR0(alu_out);
2535      }
2536      break;
2537    }
2538    case ORX: {
2539      int rs = instr->RSValue();
2540      int ra = instr->RAValue();
2541      int rb = instr->RBValue();
2542      intptr_t rs_val = get_register(rs);
2543      intptr_t rb_val = get_register(rb);
2544      intptr_t alu_out = rs_val | rb_val;
2545      set_register(ra, alu_out);
2546      if (instr->Bit(0)) {  // RC bit set
2547        SetCR0(alu_out);
2548      }
2549      break;
2550    }
2551    case ORC: {
2552      int rs = instr->RSValue();
2553      int ra = instr->RAValue();
2554      int rb = instr->RBValue();
2555      intptr_t rs_val = get_register(rs);
2556      intptr_t rb_val = get_register(rb);
2557      intptr_t alu_out = rs_val | ~rb_val;
2558      set_register(ra, alu_out);
2559      if (instr->Bit(0)) {  // RC bit set
2560        SetCR0(alu_out);
2561      }
2562      break;
2563    }
2564    case MFSPR: {
2565      int rt = instr->RTValue();
2566      int spr = instr->Bits(20, 11);
2567      if (spr != 256) {
2568        UNIMPLEMENTED();  // Only LRLR supported
2569      }
2570      set_register(rt, special_reg_lr_);
2571      break;
2572    }
2573    case MTSPR: {
2574      int rt = instr->RTValue();
2575      intptr_t rt_val = get_register(rt);
2576      int spr = instr->Bits(20, 11);
2577      if (spr == 256) {
2578        special_reg_lr_ = rt_val;
2579      } else if (spr == 288) {
2580        special_reg_ctr_ = rt_val;
2581      } else if (spr == 32) {
2582        special_reg_xer_ = rt_val;
2583      } else {
2584        UNIMPLEMENTED();  // Only LR supported
2585      }
2586      break;
2587    }
2588    case MFCR: {
2589      int rt = instr->RTValue();
2590      set_register(rt, condition_reg_);
2591      break;
2592    }
2593    case STWUX:
2594    case STWX: {
2595      int rs = instr->RSValue();
2596      int ra = instr->RAValue();
2597      int rb = instr->RBValue();
2598      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2599      int32_t rs_val = get_register(rs);
2600      intptr_t rb_val = get_register(rb);
2601      WriteW(ra_val + rb_val, rs_val, instr);
2602      if (opcode == STWUX) {
2603        DCHECK(ra != 0);
2604        set_register(ra, ra_val + rb_val);
2605      }
2606      break;
2607    }
2608    case STBUX:
2609    case STBX: {
2610      int rs = instr->RSValue();
2611      int ra = instr->RAValue();
2612      int rb = instr->RBValue();
2613      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2614      int8_t rs_val = get_register(rs);
2615      intptr_t rb_val = get_register(rb);
2616      WriteB(ra_val + rb_val, rs_val);
2617      if (opcode == STBUX) {
2618        DCHECK(ra != 0);
2619        set_register(ra, ra_val + rb_val);
2620      }
2621      break;
2622    }
2623    case STHUX:
2624    case STHX: {
2625      int rs = instr->RSValue();
2626      int ra = instr->RAValue();
2627      int rb = instr->RBValue();
2628      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2629      int16_t rs_val = get_register(rs);
2630      intptr_t rb_val = get_register(rb);
2631      WriteH(ra_val + rb_val, rs_val, instr);
2632      if (opcode == STHUX) {
2633        DCHECK(ra != 0);
2634        set_register(ra, ra_val + rb_val);
2635      }
2636      break;
2637    }
2638    case LWZX:
2639    case LWZUX: {
2640      int rt = instr->RTValue();
2641      int ra = instr->RAValue();
2642      int rb = instr->RBValue();
2643      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2644      intptr_t rb_val = get_register(rb);
2645      set_register(rt, ReadWU(ra_val + rb_val, instr));
2646      if (opcode == LWZUX) {
2647        DCHECK(ra != 0 && ra != rt);
2648        set_register(ra, ra_val + rb_val);
2649      }
2650      break;
2651    }
2652#if V8_TARGET_ARCH_PPC64
2653    case LWAX: {
2654      int rt = instr->RTValue();
2655      int ra = instr->RAValue();
2656      int rb = instr->RBValue();
2657      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2658      intptr_t rb_val = get_register(rb);
2659      set_register(rt, ReadW(ra_val + rb_val, instr));
2660      break;
2661    }
2662    case LDX:
2663    case LDUX: {
2664      int rt = instr->RTValue();
2665      int ra = instr->RAValue();
2666      int rb = instr->RBValue();
2667      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2668      intptr_t rb_val = get_register(rb);
2669      intptr_t* result = ReadDW(ra_val + rb_val);
2670      set_register(rt, *result);
2671      if (opcode == LDUX) {
2672        DCHECK(ra != 0 && ra != rt);
2673        set_register(ra, ra_val + rb_val);
2674      }
2675      break;
2676    }
2677    case STDX:
2678    case STDUX: {
2679      int rs = instr->RSValue();
2680      int ra = instr->RAValue();
2681      int rb = instr->RBValue();
2682      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2683      intptr_t rs_val = get_register(rs);
2684      intptr_t rb_val = get_register(rb);
2685      WriteDW(ra_val + rb_val, rs_val);
2686      if (opcode == STDUX) {
2687        DCHECK(ra != 0);
2688        set_register(ra, ra_val + rb_val);
2689      }
2690      break;
2691    }
2692#endif
2693    case LBZX:
2694    case LBZUX: {
2695      int rt = instr->RTValue();
2696      int ra = instr->RAValue();
2697      int rb = instr->RBValue();
2698      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2699      intptr_t rb_val = get_register(rb);
2700      set_register(rt, ReadBU(ra_val + rb_val) & 0xFF);
2701      if (opcode == LBZUX) {
2702        DCHECK(ra != 0 && ra != rt);
2703        set_register(ra, ra_val + rb_val);
2704      }
2705      break;
2706    }
2707    case LHZX:
2708    case LHZUX: {
2709      int rt = instr->RTValue();
2710      int ra = instr->RAValue();
2711      int rb = instr->RBValue();
2712      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2713      intptr_t rb_val = get_register(rb);
2714      set_register(rt, ReadHU(ra_val + rb_val, instr) & 0xFFFF);
2715      if (opcode == LHZUX) {
2716        DCHECK(ra != 0 && ra != rt);
2717        set_register(ra, ra_val + rb_val);
2718      }
2719      break;
2720    }
2721    case LHAX:
2722    case LHAUX: {
2723      int rt = instr->RTValue();
2724      int ra = instr->RAValue();
2725      int rb = instr->RBValue();
2726      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2727      intptr_t rb_val = get_register(rb);
2728      set_register(rt, ReadH(ra_val + rb_val, instr));
2729      if (opcode == LHAUX) {
2730        DCHECK(ra != 0 && ra != rt);
2731        set_register(ra, ra_val + rb_val);
2732      }
2733      break;
2734    }
2735    case DCBF: {
2736      // todo - simulate dcbf
2737      break;
2738    }
2739    default: {
2740      found = false;
2741      break;
2742    }
2743  }
2744
2745  return found;
2746}
2747
2748
2749void Simulator::ExecuteExt2_5bit(Instruction* instr) {
2750  int opcode = instr->Bits(5, 1) << 1;
2751  switch (opcode) {
2752    case ISEL: {
2753      int rt = instr->RTValue();
2754      int ra = instr->RAValue();
2755      int rb = instr->RBValue();
2756      int condition_bit = instr->RCValue();
2757      int condition_mask = 0x80000000 >> condition_bit;
2758      intptr_t ra_val = (ra == 0) ? 0 : get_register(ra);
2759      intptr_t rb_val = get_register(rb);
2760      intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val;
2761      set_register(rt, value);
2762      break;
2763    }
2764    default: {
2765      PrintF("Unimplemented: %08x\n", instr->InstructionBits());
2766      UNIMPLEMENTED();  // Not used by V8.
2767    }
2768  }
2769}
2770
2771
2772void Simulator::ExecuteExt2(Instruction* instr) {
2773  // Check first the 10-1 bit versions
2774  if (ExecuteExt2_10bit(instr)) return;
2775  // Now look at the lesser encodings
2776  if (ExecuteExt2_9bit_part1(instr)) return;
2777  if (ExecuteExt2_9bit_part2(instr)) return;
2778  ExecuteExt2_5bit(instr);
2779}
2780
2781
2782void Simulator::ExecuteExt3(Instruction* instr) {
2783  int opcode = instr->Bits(10, 1) << 1;
2784  switch (opcode) {
2785    case FCFID: {
2786      // fcfids
2787      int frt = instr->RTValue();
2788      int frb = instr->RBValue();
2789      int64_t frb_val = get_d_register(frb);
2790      double frt_val = static_cast<float>(frb_val);
2791      set_d_register_from_double(frt, frt_val);
2792      return;
2793    }
2794    case FCFIDU: {
2795      // fcfidus
2796      int frt = instr->RTValue();
2797      int frb = instr->RBValue();
2798      uint64_t frb_val = get_d_register(frb);
2799      double frt_val = static_cast<float>(frb_val);
2800      set_d_register_from_double(frt, frt_val);
2801      return;
2802    }
2803  }
2804  UNIMPLEMENTED();  // Not used by V8.
2805}
2806
2807
2808void Simulator::ExecuteExt4(Instruction* instr) {
2809  switch (instr->Bits(5, 1) << 1) {
2810    case FDIV: {
2811      int frt = instr->RTValue();
2812      int fra = instr->RAValue();
2813      int frb = instr->RBValue();
2814      double fra_val = get_double_from_d_register(fra);
2815      double frb_val = get_double_from_d_register(frb);
2816      double frt_val = fra_val / frb_val;
2817      set_d_register_from_double(frt, frt_val);
2818      return;
2819    }
2820    case FSUB: {
2821      int frt = instr->RTValue();
2822      int fra = instr->RAValue();
2823      int frb = instr->RBValue();
2824      double fra_val = get_double_from_d_register(fra);
2825      double frb_val = get_double_from_d_register(frb);
2826      double frt_val = fra_val - frb_val;
2827      set_d_register_from_double(frt, frt_val);
2828      return;
2829    }
2830    case FADD: {
2831      int frt = instr->RTValue();
2832      int fra = instr->RAValue();
2833      int frb = instr->RBValue();
2834      double fra_val = get_double_from_d_register(fra);
2835      double frb_val = get_double_from_d_register(frb);
2836      double frt_val = fra_val + frb_val;
2837      set_d_register_from_double(frt, frt_val);
2838      return;
2839    }
2840    case FSQRT: {
2841      lazily_initialize_fast_sqrt(isolate_);
2842      int frt = instr->RTValue();
2843      int frb = instr->RBValue();
2844      double frb_val = get_double_from_d_register(frb);
2845      double frt_val = fast_sqrt(frb_val, isolate_);
2846      set_d_register_from_double(frt, frt_val);
2847      return;
2848    }
2849    case FSEL: {
2850      int frt = instr->RTValue();
2851      int fra = instr->RAValue();
2852      int frb = instr->RBValue();
2853      int frc = instr->RCValue();
2854      double fra_val = get_double_from_d_register(fra);
2855      double frb_val = get_double_from_d_register(frb);
2856      double frc_val = get_double_from_d_register(frc);
2857      double frt_val = ((fra_val >= 0.0) ? frc_val : frb_val);
2858      set_d_register_from_double(frt, frt_val);
2859      return;
2860    }
2861    case FMUL: {
2862      int frt = instr->RTValue();
2863      int fra = instr->RAValue();
2864      int frc = instr->RCValue();
2865      double fra_val = get_double_from_d_register(fra);
2866      double frc_val = get_double_from_d_register(frc);
2867      double frt_val = fra_val * frc_val;
2868      set_d_register_from_double(frt, frt_val);
2869      return;
2870    }
2871    case FMSUB: {
2872      int frt = instr->RTValue();
2873      int fra = instr->RAValue();
2874      int frb = instr->RBValue();
2875      int frc = instr->RCValue();
2876      double fra_val = get_double_from_d_register(fra);
2877      double frb_val = get_double_from_d_register(frb);
2878      double frc_val = get_double_from_d_register(frc);
2879      double frt_val = (fra_val * frc_val) - frb_val;
2880      set_d_register_from_double(frt, frt_val);
2881      return;
2882    }
2883    case FMADD: {
2884      int frt = instr->RTValue();
2885      int fra = instr->RAValue();
2886      int frb = instr->RBValue();
2887      int frc = instr->RCValue();
2888      double fra_val = get_double_from_d_register(fra);
2889      double frb_val = get_double_from_d_register(frb);
2890      double frc_val = get_double_from_d_register(frc);
2891      double frt_val = (fra_val * frc_val) + frb_val;
2892      set_d_register_from_double(frt, frt_val);
2893      return;
2894    }
2895  }
2896  int opcode = instr->Bits(10, 1) << 1;
2897  switch (opcode) {
2898    case FCMPU: {
2899      int fra = instr->RAValue();
2900      int frb = instr->RBValue();
2901      double fra_val = get_double_from_d_register(fra);
2902      double frb_val = get_double_from_d_register(frb);
2903      int cr = instr->Bits(25, 23);
2904      int bf = 0;
2905      if (fra_val < frb_val) {
2906        bf |= 0x80000000;
2907      }
2908      if (fra_val > frb_val) {
2909        bf |= 0x40000000;
2910      }
2911      if (fra_val == frb_val) {
2912        bf |= 0x20000000;
2913      }
2914      if (std::isunordered(fra_val, frb_val)) {
2915        bf |= 0x10000000;
2916      }
2917      int condition_mask = 0xF0000000 >> (cr * 4);
2918      int condition = bf >> (cr * 4);
2919      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
2920      return;
2921    }
2922    case FRIN: {
2923      int frt = instr->RTValue();
2924      int frb = instr->RBValue();
2925      double frb_val = get_double_from_d_register(frb);
2926      double frt_val = std::round(frb_val);
2927      set_d_register_from_double(frt, frt_val);
2928      if (instr->Bit(0)) {  // RC bit set
2929                            //  UNIMPLEMENTED();
2930      }
2931      return;
2932    }
2933    case FRIZ: {
2934      int frt = instr->RTValue();
2935      int frb = instr->RBValue();
2936      double frb_val = get_double_from_d_register(frb);
2937      double frt_val = std::trunc(frb_val);
2938      set_d_register_from_double(frt, frt_val);
2939      if (instr->Bit(0)) {  // RC bit set
2940                            //  UNIMPLEMENTED();
2941      }
2942      return;
2943    }
2944    case FRIP: {
2945      int frt = instr->RTValue();
2946      int frb = instr->RBValue();
2947      double frb_val = get_double_from_d_register(frb);
2948      double frt_val = std::ceil(frb_val);
2949      set_d_register_from_double(frt, frt_val);
2950      if (instr->Bit(0)) {  // RC bit set
2951                            //  UNIMPLEMENTED();
2952      }
2953      return;
2954    }
2955    case FRIM: {
2956      int frt = instr->RTValue();
2957      int frb = instr->RBValue();
2958      double frb_val = get_double_from_d_register(frb);
2959      double frt_val = std::floor(frb_val);
2960      set_d_register_from_double(frt, frt_val);
2961      if (instr->Bit(0)) {  // RC bit set
2962                            //  UNIMPLEMENTED();
2963      }
2964      return;
2965    }
2966    case FRSP: {
2967      int frt = instr->RTValue();
2968      int frb = instr->RBValue();
2969      // frsp round 8-byte double-precision value to
2970      // single-precision value
2971      double frb_val = get_double_from_d_register(frb);
2972      double frt_val = static_cast<float>(frb_val);
2973      set_d_register_from_double(frt, frt_val);
2974      if (instr->Bit(0)) {  // RC bit set
2975                            //  UNIMPLEMENTED();
2976      }
2977      return;
2978    }
2979    case FCFID: {
2980      int frt = instr->RTValue();
2981      int frb = instr->RBValue();
2982      int64_t frb_val = get_d_register(frb);
2983      double frt_val = static_cast<double>(frb_val);
2984      set_d_register_from_double(frt, frt_val);
2985      return;
2986    }
2987    case FCFIDU: {
2988      int frt = instr->RTValue();
2989      int frb = instr->RBValue();
2990      uint64_t frb_val = get_d_register(frb);
2991      double frt_val = static_cast<double>(frb_val);
2992      set_d_register_from_double(frt, frt_val);
2993      return;
2994    }
2995    case FCTID:
2996    case FCTIDZ: {
2997      int frt = instr->RTValue();
2998      int frb = instr->RBValue();
2999      double frb_val = get_double_from_d_register(frb);
3000      int mode = (opcode == FCTIDZ) ? kRoundToZero
3001                                    : (fp_condition_reg_ & kFPRoundingModeMask);
3002      int64_t frt_val;
3003      int64_t one = 1;  // work-around gcc
3004      int64_t kMinVal = (one << 63);
3005      int64_t kMaxVal = kMinVal - 1;
3006      bool invalid_convert = false;
3007
3008      if (std::isnan(frb_val)) {
3009        frt_val = kMinVal;
3010        invalid_convert = true;
3011      } else {
3012        switch (mode) {
3013          case kRoundToZero:
3014            frb_val = std::trunc(frb_val);
3015            break;
3016          case kRoundToPlusInf:
3017            frb_val = std::ceil(frb_val);
3018            break;
3019          case kRoundToMinusInf:
3020            frb_val = std::floor(frb_val);
3021            break;
3022          default:
3023            UNIMPLEMENTED();  // Not used by V8.
3024            break;
3025        }
3026        if (frb_val < static_cast<double>(kMinVal)) {
3027          frt_val = kMinVal;
3028          invalid_convert = true;
3029        } else if (frb_val >= static_cast<double>(kMaxVal)) {
3030          frt_val = kMaxVal;
3031          invalid_convert = true;
3032        } else {
3033          frt_val = (int64_t)frb_val;
3034        }
3035      }
3036      set_d_register(frt, frt_val);
3037      if (invalid_convert) SetFPSCR(VXCVI);
3038      return;
3039    }
3040    case FCTIDU:
3041    case FCTIDUZ: {
3042      int frt = instr->RTValue();
3043      int frb = instr->RBValue();
3044      double frb_val = get_double_from_d_register(frb);
3045      int mode = (opcode == FCTIDUZ)
3046                     ? kRoundToZero
3047                     : (fp_condition_reg_ & kFPRoundingModeMask);
3048      uint64_t frt_val;
3049      uint64_t kMinVal = 0;
3050      uint64_t kMaxVal = kMinVal - 1;
3051      bool invalid_convert = false;
3052
3053      if (std::isnan(frb_val)) {
3054        frt_val = kMinVal;
3055        invalid_convert = true;
3056      } else {
3057        switch (mode) {
3058          case kRoundToZero:
3059            frb_val = std::trunc(frb_val);
3060            break;
3061          case kRoundToPlusInf:
3062            frb_val = std::ceil(frb_val);
3063            break;
3064          case kRoundToMinusInf:
3065            frb_val = std::floor(frb_val);
3066            break;
3067          default:
3068            UNIMPLEMENTED();  // Not used by V8.
3069            break;
3070        }
3071        if (frb_val < static_cast<double>(kMinVal)) {
3072          frt_val = kMinVal;
3073          invalid_convert = true;
3074        } else if (frb_val >= static_cast<double>(kMaxVal)) {
3075          frt_val = kMaxVal;
3076          invalid_convert = true;
3077        } else {
3078          frt_val = (uint64_t)frb_val;
3079        }
3080      }
3081      set_d_register(frt, frt_val);
3082      if (invalid_convert) SetFPSCR(VXCVI);
3083      return;
3084    }
3085    case FCTIW:
3086    case FCTIWZ: {
3087      int frt = instr->RTValue();
3088      int frb = instr->RBValue();
3089      double frb_val = get_double_from_d_register(frb);
3090      int mode = (opcode == FCTIWZ) ? kRoundToZero
3091                                    : (fp_condition_reg_ & kFPRoundingModeMask);
3092      int64_t frt_val;
3093      int64_t kMinVal = kMinInt;
3094      int64_t kMaxVal = kMaxInt;
3095
3096      if (std::isnan(frb_val)) {
3097        frt_val = kMinVal;
3098      } else {
3099        switch (mode) {
3100          case kRoundToZero:
3101            frb_val = std::trunc(frb_val);
3102            break;
3103          case kRoundToPlusInf:
3104            frb_val = std::ceil(frb_val);
3105            break;
3106          case kRoundToMinusInf:
3107            frb_val = std::floor(frb_val);
3108            break;
3109          case kRoundToNearest: {
3110            double orig = frb_val;
3111            frb_val = lround(frb_val);
3112            // Round to even if exactly halfway.  (lround rounds up)
3113            if (std::fabs(frb_val - orig) == 0.5 && ((int64_t)frb_val % 2)) {
3114              frb_val += ((frb_val > 0) ? -1.0 : 1.0);
3115            }
3116            break;
3117          }
3118          default:
3119            UNIMPLEMENTED();  // Not used by V8.
3120            break;
3121        }
3122        if (frb_val < kMinVal) {
3123          frt_val = kMinVal;
3124        } else if (frb_val > kMaxVal) {
3125          frt_val = kMaxVal;
3126        } else {
3127          frt_val = (int64_t)frb_val;
3128        }
3129      }
3130      set_d_register(frt, frt_val);
3131      return;
3132    }
3133    case FNEG: {
3134      int frt = instr->RTValue();
3135      int frb = instr->RBValue();
3136      double frb_val = get_double_from_d_register(frb);
3137      double frt_val = -frb_val;
3138      set_d_register_from_double(frt, frt_val);
3139      return;
3140    }
3141    case FMR: {
3142      int frt = instr->RTValue();
3143      int frb = instr->RBValue();
3144      int64_t frb_val = get_d_register(frb);
3145      set_d_register(frt, frb_val);
3146      return;
3147    }
3148    case MTFSFI: {
3149      int bf = instr->Bits(25, 23);
3150      int imm = instr->Bits(15, 12);
3151      int fp_condition_mask = 0xF0000000 >> (bf * 4);
3152      fp_condition_reg_ &= ~fp_condition_mask;
3153      fp_condition_reg_ |= (imm << (28 - (bf * 4)));
3154      if (instr->Bit(0)) {  // RC bit set
3155        condition_reg_ &= 0xF0FFFFFF;
3156        condition_reg_ |= (imm << 23);
3157      }
3158      return;
3159    }
3160    case MTFSF: {
3161      int frb = instr->RBValue();
3162      int64_t frb_dval = get_d_register(frb);
3163      int32_t frb_ival = static_cast<int32_t>((frb_dval)&0xffffffff);
3164      int l = instr->Bits(25, 25);
3165      if (l == 1) {
3166        fp_condition_reg_ = frb_ival;
3167      } else {
3168        UNIMPLEMENTED();
3169      }
3170      if (instr->Bit(0)) {  // RC bit set
3171        UNIMPLEMENTED();
3172        // int w = instr->Bits(16, 16);
3173        // int flm = instr->Bits(24, 17);
3174      }
3175      return;
3176    }
3177    case MFFS: {
3178      int frt = instr->RTValue();
3179      int64_t lval = static_cast<int64_t>(fp_condition_reg_);
3180      set_d_register(frt, lval);
3181      return;
3182    }
3183    case MCRFS: {
3184      int bf = instr->Bits(25, 23);
3185      int bfa = instr->Bits(20, 18);
3186      int cr_shift = (7 - bf) * CRWIDTH;
3187      int fp_shift = (7 - bfa) * CRWIDTH;
3188      int field_val = (fp_condition_reg_ >> fp_shift) & 0xf;
3189      condition_reg_ &= ~(0x0f << cr_shift);
3190      condition_reg_ |= (field_val << cr_shift);
3191      // Clear copied exception bits
3192      switch (bfa) {
3193        case 5:
3194          ClearFPSCR(VXSOFT);
3195          ClearFPSCR(VXSQRT);
3196          ClearFPSCR(VXCVI);
3197          break;
3198        default:
3199          UNIMPLEMENTED();
3200          break;
3201      }
3202      return;
3203    }
3204    case MTFSB0: {
3205      int bt = instr->Bits(25, 21);
3206      ClearFPSCR(bt);
3207      if (instr->Bit(0)) {  // RC bit set
3208        UNIMPLEMENTED();
3209      }
3210      return;
3211    }
3212    case MTFSB1: {
3213      int bt = instr->Bits(25, 21);
3214      SetFPSCR(bt);
3215      if (instr->Bit(0)) {  // RC bit set
3216        UNIMPLEMENTED();
3217      }
3218      return;
3219    }
3220    case FABS: {
3221      int frt = instr->RTValue();
3222      int frb = instr->RBValue();
3223      double frb_val = get_double_from_d_register(frb);
3224      double frt_val = std::fabs(frb_val);
3225      set_d_register_from_double(frt, frt_val);
3226      return;
3227    }
3228  }
3229  UNIMPLEMENTED();  // Not used by V8.
3230}
3231
3232#if V8_TARGET_ARCH_PPC64
3233void Simulator::ExecuteExt5(Instruction* instr) {
3234  switch (instr->Bits(4, 2) << 2) {
3235    case RLDICL: {
3236      int ra = instr->RAValue();
3237      int rs = instr->RSValue();
3238      uintptr_t rs_val = get_register(rs);
3239      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3240      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3241      DCHECK(sh >= 0 && sh <= 63);
3242      DCHECK(mb >= 0 && mb <= 63);
3243      uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3244      uintptr_t mask = 0xffffffffffffffff >> mb;
3245      result &= mask;
3246      set_register(ra, result);
3247      if (instr->Bit(0)) {  // RC bit set
3248        SetCR0(result);
3249      }
3250      return;
3251    }
3252    case RLDICR: {
3253      int ra = instr->RAValue();
3254      int rs = instr->RSValue();
3255      uintptr_t rs_val = get_register(rs);
3256      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3257      int me = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3258      DCHECK(sh >= 0 && sh <= 63);
3259      DCHECK(me >= 0 && me <= 63);
3260      uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3261      uintptr_t mask = 0xffffffffffffffff << (63 - me);
3262      result &= mask;
3263      set_register(ra, result);
3264      if (instr->Bit(0)) {  // RC bit set
3265        SetCR0(result);
3266      }
3267      return;
3268    }
3269    case RLDIC: {
3270      int ra = instr->RAValue();
3271      int rs = instr->RSValue();
3272      uintptr_t rs_val = get_register(rs);
3273      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3274      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3275      DCHECK(sh >= 0 && sh <= 63);
3276      DCHECK(mb >= 0 && mb <= 63);
3277      uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3278      uintptr_t mask = (0xffffffffffffffff >> mb) & (0xffffffffffffffff << sh);
3279      result &= mask;
3280      set_register(ra, result);
3281      if (instr->Bit(0)) {  // RC bit set
3282        SetCR0(result);
3283      }
3284      return;
3285    }
3286    case RLDIMI: {
3287      int ra = instr->RAValue();
3288      int rs = instr->RSValue();
3289      uintptr_t rs_val = get_register(rs);
3290      intptr_t ra_val = get_register(ra);
3291      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3292      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3293      int me = 63 - sh;
3294      uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3295      uintptr_t mask = 0;
3296      if (mb < me + 1) {
3297        uintptr_t bit = 0x8000000000000000 >> mb;
3298        for (; mb <= me; mb++) {
3299          mask |= bit;
3300          bit >>= 1;
3301        }
3302      } else if (mb == me + 1) {
3303        mask = 0xffffffffffffffff;
3304      } else {                                           // mb > me+1
3305        uintptr_t bit = 0x8000000000000000 >> (me + 1);  // needs to be tested
3306        mask = 0xffffffffffffffff;
3307        for (; me < mb; me++) {
3308          mask ^= bit;
3309          bit >>= 1;
3310        }
3311      }
3312      result &= mask;
3313      ra_val &= ~mask;
3314      result |= ra_val;
3315      set_register(ra, result);
3316      if (instr->Bit(0)) {  // RC bit set
3317        SetCR0(result);
3318      }
3319      return;
3320    }
3321  }
3322  switch (instr->Bits(4, 1) << 1) {
3323    case RLDCL: {
3324      int ra = instr->RAValue();
3325      int rs = instr->RSValue();
3326      int rb = instr->RBValue();
3327      uintptr_t rs_val = get_register(rs);
3328      uintptr_t rb_val = get_register(rb);
3329      int sh = (rb_val & 0x3f);
3330      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3331      DCHECK(sh >= 0 && sh <= 63);
3332      DCHECK(mb >= 0 && mb <= 63);
3333      uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3334      uintptr_t mask = 0xffffffffffffffff >> mb;
3335      result &= mask;
3336      set_register(ra, result);
3337      if (instr->Bit(0)) {  // RC bit set
3338        SetCR0(result);
3339      }
3340      return;
3341    }
3342  }
3343  UNIMPLEMENTED();  // Not used by V8.
3344}
3345#endif
3346
3347
3348void Simulator::ExecuteGeneric(Instruction* instr) {
3349  int opcode = instr->OpcodeValue() << 26;
3350  switch (opcode) {
3351    case SUBFIC: {
3352      int rt = instr->RTValue();
3353      int ra = instr->RAValue();
3354      intptr_t ra_val = get_register(ra);
3355      int32_t im_val = instr->Bits(15, 0);
3356      im_val = SIGN_EXT_IMM16(im_val);
3357      intptr_t alu_out = im_val - ra_val;
3358      set_register(rt, alu_out);
3359      // todo - handle RC bit
3360      break;
3361    }
3362    case CMPLI: {
3363      int ra = instr->RAValue();
3364      uint32_t im_val = instr->Bits(15, 0);
3365      int cr = instr->Bits(25, 23);
3366      uint32_t bf = 0;
3367#if V8_TARGET_ARCH_PPC64
3368      int L = instr->Bit(21);
3369      if (L) {
3370#endif
3371        uintptr_t ra_val = get_register(ra);
3372        if (ra_val < im_val) {
3373          bf |= 0x80000000;
3374        }
3375        if (ra_val > im_val) {
3376          bf |= 0x40000000;
3377        }
3378        if (ra_val == im_val) {
3379          bf |= 0x20000000;
3380        }
3381#if V8_TARGET_ARCH_PPC64
3382      } else {
3383        uint32_t ra_val = get_register(ra);
3384        if (ra_val < im_val) {
3385          bf |= 0x80000000;
3386        }
3387        if (ra_val > im_val) {
3388          bf |= 0x40000000;
3389        }
3390        if (ra_val == im_val) {
3391          bf |= 0x20000000;
3392        }
3393      }
3394#endif
3395      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
3396      uint32_t condition = bf >> (cr * 4);
3397      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
3398      break;
3399    }
3400    case CMPI: {
3401      int ra = instr->RAValue();
3402      int32_t im_val = instr->Bits(15, 0);
3403      im_val = SIGN_EXT_IMM16(im_val);
3404      int cr = instr->Bits(25, 23);
3405      uint32_t bf = 0;
3406#if V8_TARGET_ARCH_PPC64
3407      int L = instr->Bit(21);
3408      if (L) {
3409#endif
3410        intptr_t ra_val = get_register(ra);
3411        if (ra_val < im_val) {
3412          bf |= 0x80000000;
3413        }
3414        if (ra_val > im_val) {
3415          bf |= 0x40000000;
3416        }
3417        if (ra_val == im_val) {
3418          bf |= 0x20000000;
3419        }
3420#if V8_TARGET_ARCH_PPC64
3421      } else {
3422        int32_t ra_val = get_register(ra);
3423        if (ra_val < im_val) {
3424          bf |= 0x80000000;
3425        }
3426        if (ra_val > im_val) {
3427          bf |= 0x40000000;
3428        }
3429        if (ra_val == im_val) {
3430          bf |= 0x20000000;
3431        }
3432      }
3433#endif
3434      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
3435      uint32_t condition = bf >> (cr * 4);
3436      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
3437      break;
3438    }
3439    case ADDIC: {
3440      int rt = instr->RTValue();
3441      int ra = instr->RAValue();
3442      uintptr_t ra_val = get_register(ra);
3443      uintptr_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0));
3444      uintptr_t alu_out = ra_val + im_val;
3445      // Check overflow
3446      if (~ra_val < im_val) {
3447        special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
3448      } else {
3449        special_reg_xer_ &= ~0xF0000000;
3450      }
3451      set_register(rt, alu_out);
3452      break;
3453    }
3454    case ADDI: {
3455      int rt = instr->RTValue();
3456      int ra = instr->RAValue();
3457      int32_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0));
3458      intptr_t alu_out;
3459      if (ra == 0) {
3460        alu_out = im_val;
3461      } else {
3462        intptr_t ra_val = get_register(ra);
3463        alu_out = ra_val + im_val;
3464      }
3465      set_register(rt, alu_out);
3466      // todo - handle RC bit
3467      break;
3468    }
3469    case ADDIS: {
3470      int rt = instr->RTValue();
3471      int ra = instr->RAValue();
3472      int32_t im_val = (instr->Bits(15, 0) << 16);
3473      intptr_t alu_out;
3474      if (ra == 0) {  // treat r0 as zero
3475        alu_out = im_val;
3476      } else {
3477        intptr_t ra_val = get_register(ra);
3478        alu_out = ra_val + im_val;
3479      }
3480      set_register(rt, alu_out);
3481      break;
3482    }
3483    case BCX: {
3484      ExecuteBranchConditional(instr, BC_OFFSET);
3485      break;
3486    }
3487    case BX: {
3488      int offset = (instr->Bits(25, 2) << 8) >> 6;
3489      if (instr->Bit(0) == 1) {  // LK flag set
3490        special_reg_lr_ = get_pc() + 4;
3491      }
3492      set_pc(get_pc() + offset);
3493      // todo - AA flag
3494      break;
3495    }
3496    case EXT1: {
3497      ExecuteExt1(instr);
3498      break;
3499    }
3500    case RLWIMIX: {
3501      int ra = instr->RAValue();
3502      int rs = instr->RSValue();
3503      uint32_t rs_val = get_register(rs);
3504      int32_t ra_val = get_register(ra);
3505      int sh = instr->Bits(15, 11);
3506      int mb = instr->Bits(10, 6);
3507      int me = instr->Bits(5, 1);
3508      uint32_t result = base::bits::RotateLeft32(rs_val, sh);
3509      int mask = 0;
3510      if (mb < me + 1) {
3511        int bit = 0x80000000 >> mb;
3512        for (; mb <= me; mb++) {
3513          mask |= bit;
3514          bit >>= 1;
3515        }
3516      } else if (mb == me + 1) {
3517        mask = 0xffffffff;
3518      } else {                             // mb > me+1
3519        int bit = 0x80000000 >> (me + 1);  // needs to be tested
3520        mask = 0xffffffff;
3521        for (; me < mb; me++) {
3522          mask ^= bit;
3523          bit >>= 1;
3524        }
3525      }
3526      result &= mask;
3527      ra_val &= ~mask;
3528      result |= ra_val;
3529      set_register(ra, result);
3530      if (instr->Bit(0)) {  // RC bit set
3531        SetCR0(result);
3532      }
3533      break;
3534    }
3535    case RLWINMX:
3536    case RLWNMX: {
3537      int ra = instr->RAValue();
3538      int rs = instr->RSValue();
3539      uint32_t rs_val = get_register(rs);
3540      int sh = 0;
3541      if (opcode == RLWINMX) {
3542        sh = instr->Bits(15, 11);
3543      } else {
3544        int rb = instr->RBValue();
3545        uint32_t rb_val = get_register(rb);
3546        sh = (rb_val & 0x1f);
3547      }
3548      int mb = instr->Bits(10, 6);
3549      int me = instr->Bits(5, 1);
3550      uint32_t result = base::bits::RotateLeft32(rs_val, sh);
3551      int mask = 0;
3552      if (mb < me + 1) {
3553        int bit = 0x80000000 >> mb;
3554        for (; mb <= me; mb++) {
3555          mask |= bit;
3556          bit >>= 1;
3557        }
3558      } else if (mb == me + 1) {
3559        mask = 0xffffffff;
3560      } else {                             // mb > me+1
3561        int bit = 0x80000000 >> (me + 1);  // needs to be tested
3562        mask = 0xffffffff;
3563        for (; me < mb; me++) {
3564          mask ^= bit;
3565          bit >>= 1;
3566        }
3567      }
3568      result &= mask;
3569      set_register(ra, result);
3570      if (instr->Bit(0)) {  // RC bit set
3571        SetCR0(result);
3572      }
3573      break;
3574    }
3575    case ORI: {
3576      int rs = instr->RSValue();
3577      int ra = instr->RAValue();
3578      intptr_t rs_val = get_register(rs);
3579      uint32_t im_val = instr->Bits(15, 0);
3580      intptr_t alu_out = rs_val | im_val;
3581      set_register(ra, alu_out);
3582      break;
3583    }
3584    case ORIS: {
3585      int rs = instr->RSValue();
3586      int ra = instr->RAValue();
3587      intptr_t rs_val = get_register(rs);
3588      uint32_t im_val = instr->Bits(15, 0);
3589      intptr_t alu_out = rs_val | (im_val << 16);
3590      set_register(ra, alu_out);
3591      break;
3592    }
3593    case XORI: {
3594      int rs = instr->RSValue();
3595      int ra = instr->RAValue();
3596      intptr_t rs_val = get_register(rs);
3597      uint32_t im_val = instr->Bits(15, 0);
3598      intptr_t alu_out = rs_val ^ im_val;
3599      set_register(ra, alu_out);
3600      // todo - set condition based SO bit
3601      break;
3602    }
3603    case XORIS: {
3604      int rs = instr->RSValue();
3605      int ra = instr->RAValue();
3606      intptr_t rs_val = get_register(rs);
3607      uint32_t im_val = instr->Bits(15, 0);
3608      intptr_t alu_out = rs_val ^ (im_val << 16);
3609      set_register(ra, alu_out);
3610      break;
3611    }
3612    case ANDIx: {
3613      int rs = instr->RSValue();
3614      int ra = instr->RAValue();
3615      intptr_t rs_val = get_register(rs);
3616      uint32_t im_val = instr->Bits(15, 0);
3617      intptr_t alu_out = rs_val & im_val;
3618      set_register(ra, alu_out);
3619      SetCR0(alu_out);
3620      break;
3621    }
3622    case ANDISx: {
3623      int rs = instr->RSValue();
3624      int ra = instr->RAValue();
3625      intptr_t rs_val = get_register(rs);
3626      uint32_t im_val = instr->Bits(15, 0);
3627      intptr_t alu_out = rs_val & (im_val << 16);
3628      set_register(ra, alu_out);
3629      SetCR0(alu_out);
3630      break;
3631    }
3632    case EXT2: {
3633      ExecuteExt2(instr);
3634      break;
3635    }
3636
3637    case LWZU:
3638    case LWZ: {
3639      int ra = instr->RAValue();
3640      int rt = instr->RTValue();
3641      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3642      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3643      set_register(rt, ReadWU(ra_val + offset, instr));
3644      if (opcode == LWZU) {
3645        DCHECK(ra != 0);
3646        set_register(ra, ra_val + offset);
3647      }
3648      break;
3649    }
3650
3651    case LBZU:
3652    case LBZ: {
3653      int ra = instr->RAValue();
3654      int rt = instr->RTValue();
3655      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3656      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3657      set_register(rt, ReadB(ra_val + offset) & 0xFF);
3658      if (opcode == LBZU) {
3659        DCHECK(ra != 0);
3660        set_register(ra, ra_val + offset);
3661      }
3662      break;
3663    }
3664
3665    case STWU:
3666    case STW: {
3667      int ra = instr->RAValue();
3668      int rs = instr->RSValue();
3669      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3670      int32_t rs_val = get_register(rs);
3671      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3672      WriteW(ra_val + offset, rs_val, instr);
3673      if (opcode == STWU) {
3674        DCHECK(ra != 0);
3675        set_register(ra, ra_val + offset);
3676      }
3677      // printf("r%d %08x -> %08x\n", rs, rs_val, offset); // 0xdead
3678      break;
3679    }
3680
3681    case STBU:
3682    case STB: {
3683      int ra = instr->RAValue();
3684      int rs = instr->RSValue();
3685      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3686      int8_t rs_val = get_register(rs);
3687      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3688      WriteB(ra_val + offset, rs_val);
3689      if (opcode == STBU) {
3690        DCHECK(ra != 0);
3691        set_register(ra, ra_val + offset);
3692      }
3693      break;
3694    }
3695
3696    case LHZU:
3697    case LHZ: {
3698      int ra = instr->RAValue();
3699      int rt = instr->RTValue();
3700      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3701      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3702      uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff;
3703      set_register(rt, result);
3704      if (opcode == LHZU) {
3705        set_register(ra, ra_val + offset);
3706      }
3707      break;
3708    }
3709
3710    case LHA:
3711    case LHAU: {
3712      int ra = instr->RAValue();
3713      int rt = instr->RTValue();
3714      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3715      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3716      intptr_t result = ReadH(ra_val + offset, instr);
3717      set_register(rt, result);
3718      if (opcode == LHAU) {
3719        set_register(ra, ra_val + offset);
3720      }
3721      break;
3722    }
3723
3724    case STHU:
3725    case STH: {
3726      int ra = instr->RAValue();
3727      int rs = instr->RSValue();
3728      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3729      int16_t rs_val = get_register(rs);
3730      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3731      WriteH(ra_val + offset, rs_val, instr);
3732      if (opcode == STHU) {
3733        DCHECK(ra != 0);
3734        set_register(ra, ra_val + offset);
3735      }
3736      break;
3737    }
3738
3739    case LMW:
3740    case STMW: {
3741      UNIMPLEMENTED();
3742      break;
3743    }
3744
3745    case LFSU:
3746    case LFS: {
3747      int frt = instr->RTValue();
3748      int ra = instr->RAValue();
3749      int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3750      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3751      int32_t val = ReadW(ra_val + offset, instr);
3752      float* fptr = reinterpret_cast<float*>(&val);
3753      set_d_register_from_double(frt, static_cast<double>(*fptr));
3754      if (opcode == LFSU) {
3755        DCHECK(ra != 0);
3756        set_register(ra, ra_val + offset);
3757      }
3758      break;
3759    }
3760
3761    case LFDU:
3762    case LFD: {
3763      int frt = instr->RTValue();
3764      int ra = instr->RAValue();
3765      int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3766      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3767      int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + offset));
3768      set_d_register(frt, *dptr);
3769      if (opcode == LFDU) {
3770        DCHECK(ra != 0);
3771        set_register(ra, ra_val + offset);
3772      }
3773      break;
3774    }
3775
3776    case STFSU: {
3777      case STFS:
3778        int frs = instr->RSValue();
3779        int ra = instr->RAValue();
3780        int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3781        intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3782        float frs_val = static_cast<float>(get_double_from_d_register(frs));
3783        int32_t* p = reinterpret_cast<int32_t*>(&frs_val);
3784        WriteW(ra_val + offset, *p, instr);
3785        if (opcode == STFSU) {
3786          DCHECK(ra != 0);
3787          set_register(ra, ra_val + offset);
3788        }
3789        break;
3790    }
3791
3792    case STFDU:
3793    case STFD: {
3794      int frs = instr->RSValue();
3795      int ra = instr->RAValue();
3796      int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3797      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3798      int64_t frs_val = get_d_register(frs);
3799      WriteDW(ra_val + offset, frs_val);
3800      if (opcode == STFDU) {
3801        DCHECK(ra != 0);
3802        set_register(ra, ra_val + offset);
3803      }
3804      break;
3805    }
3806
3807    case EXT3: {
3808      ExecuteExt3(instr);
3809      break;
3810    }
3811    case EXT4: {
3812      ExecuteExt4(instr);
3813      break;
3814    }
3815
3816#if V8_TARGET_ARCH_PPC64
3817    case EXT5: {
3818      ExecuteExt5(instr);
3819      break;
3820    }
3821    case LD: {
3822      int ra = instr->RAValue();
3823      int rt = instr->RTValue();
3824      int64_t ra_val = ra == 0 ? 0 : get_register(ra);
3825      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
3826      switch (instr->Bits(1, 0)) {
3827        case 0: {  // ld
3828          intptr_t* result = ReadDW(ra_val + offset);
3829          set_register(rt, *result);
3830          break;
3831        }
3832        case 1: {  // ldu
3833          intptr_t* result = ReadDW(ra_val + offset);
3834          set_register(rt, *result);
3835          DCHECK(ra != 0);
3836          set_register(ra, ra_val + offset);
3837          break;
3838        }
3839        case 2: {  // lwa
3840          intptr_t result = ReadW(ra_val + offset, instr);
3841          set_register(rt, result);
3842          break;
3843        }
3844      }
3845      break;
3846    }
3847
3848    case STD: {
3849      int ra = instr->RAValue();
3850      int rs = instr->RSValue();
3851      int64_t ra_val = ra == 0 ? 0 : get_register(ra);
3852      int64_t rs_val = get_register(rs);
3853      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
3854      WriteDW(ra_val + offset, rs_val);
3855      if (instr->Bit(0) == 1) {  // This is the STDU form
3856        DCHECK(ra != 0);
3857        set_register(ra, ra_val + offset);
3858      }
3859      break;
3860    }
3861#endif
3862
3863    default: {
3864      UNIMPLEMENTED();
3865      break;
3866    }
3867  }
3868}  // NOLINT
3869
3870
3871void Simulator::Trace(Instruction* instr) {
3872  disasm::NameConverter converter;
3873  disasm::Disassembler dasm(converter);
3874  // use a reasonably large buffer
3875  v8::internal::EmbeddedVector<char, 256> buffer;
3876  dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
3877  PrintF("%05d  %08" V8PRIxPTR "  %s\n", icount_,
3878         reinterpret_cast<intptr_t>(instr), buffer.start());
3879}
3880
3881
3882// Executes the current instruction.
3883void Simulator::ExecuteInstruction(Instruction* instr) {
3884  if (v8::internal::FLAG_check_icache) {
3885    CheckICache(isolate_->simulator_i_cache(), instr);
3886  }
3887  pc_modified_ = false;
3888  if (::v8::internal::FLAG_trace_sim) {
3889    Trace(instr);
3890  }
3891  int opcode = instr->OpcodeValue() << 26;
3892  if (opcode == TWI) {
3893    SoftwareInterrupt(instr);
3894  } else {
3895    ExecuteGeneric(instr);
3896  }
3897  if (!pc_modified_) {
3898    set_pc(reinterpret_cast<intptr_t>(instr) + Instruction::kInstrSize);
3899  }
3900}
3901
3902
3903void Simulator::Execute() {
3904  // Get the PC to simulate. Cannot use the accessor here as we need the
3905  // raw PC value and not the one used as input to arithmetic instructions.
3906  intptr_t program_counter = get_pc();
3907
3908  if (::v8::internal::FLAG_stop_sim_at == 0) {
3909    // Fast version of the dispatch loop without checking whether the simulator
3910    // should be stopping at a particular executed instruction.
3911    while (program_counter != end_sim_pc) {
3912      Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
3913      icount_++;
3914      ExecuteInstruction(instr);
3915      program_counter = get_pc();
3916    }
3917  } else {
3918    // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
3919    // we reach the particular instuction count.
3920    while (program_counter != end_sim_pc) {
3921      Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
3922      icount_++;
3923      if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
3924        PPCDebugger dbg(this);
3925        dbg.Debug();
3926      } else {
3927        ExecuteInstruction(instr);
3928      }
3929      program_counter = get_pc();
3930    }
3931  }
3932}
3933
3934
3935void Simulator::CallInternal(byte* entry) {
3936  // Adjust JS-based stack limit to C-based stack limit.
3937  isolate_->stack_guard()->AdjustStackLimitForSimulator();
3938
3939  // Prepare to execute the code at entry
3940  if (ABI_USES_FUNCTION_DESCRIPTORS) {
3941    // entry is the function descriptor
3942    set_pc(*(reinterpret_cast<intptr_t*>(entry)));
3943  } else {
3944    // entry is the instruction address
3945    set_pc(reinterpret_cast<intptr_t>(entry));
3946  }
3947
3948  if (ABI_CALL_VIA_IP) {
3949    // Put target address in ip (for JS prologue).
3950    set_register(r12, get_pc());
3951  }
3952
3953  // Put down marker for end of simulation. The simulator will stop simulation
3954  // when the PC reaches this value. By saving the "end simulation" value into
3955  // the LR the simulation stops when returning to this call point.
3956  special_reg_lr_ = end_sim_pc;
3957
3958  // Remember the values of non-volatile registers.
3959  intptr_t r2_val = get_register(r2);
3960  intptr_t r13_val = get_register(r13);
3961  intptr_t r14_val = get_register(r14);
3962  intptr_t r15_val = get_register(r15);
3963  intptr_t r16_val = get_register(r16);
3964  intptr_t r17_val = get_register(r17);
3965  intptr_t r18_val = get_register(r18);
3966  intptr_t r19_val = get_register(r19);
3967  intptr_t r20_val = get_register(r20);
3968  intptr_t r21_val = get_register(r21);
3969  intptr_t r22_val = get_register(r22);
3970  intptr_t r23_val = get_register(r23);
3971  intptr_t r24_val = get_register(r24);
3972  intptr_t r25_val = get_register(r25);
3973  intptr_t r26_val = get_register(r26);
3974  intptr_t r27_val = get_register(r27);
3975  intptr_t r28_val = get_register(r28);
3976  intptr_t r29_val = get_register(r29);
3977  intptr_t r30_val = get_register(r30);
3978  intptr_t r31_val = get_register(fp);
3979
3980  // Set up the non-volatile registers with a known value. To be able to check
3981  // that they are preserved properly across JS execution.
3982  intptr_t callee_saved_value = icount_;
3983  set_register(r2, callee_saved_value);
3984  set_register(r13, callee_saved_value);
3985  set_register(r14, callee_saved_value);
3986  set_register(r15, callee_saved_value);
3987  set_register(r16, callee_saved_value);
3988  set_register(r17, callee_saved_value);
3989  set_register(r18, callee_saved_value);
3990  set_register(r19, callee_saved_value);
3991  set_register(r20, callee_saved_value);
3992  set_register(r21, callee_saved_value);
3993  set_register(r22, callee_saved_value);
3994  set_register(r23, callee_saved_value);
3995  set_register(r24, callee_saved_value);
3996  set_register(r25, callee_saved_value);
3997  set_register(r26, callee_saved_value);
3998  set_register(r27, callee_saved_value);
3999  set_register(r28, callee_saved_value);
4000  set_register(r29, callee_saved_value);
4001  set_register(r30, callee_saved_value);
4002  set_register(fp, callee_saved_value);
4003
4004  // Start the simulation
4005  Execute();
4006
4007  // Check that the non-volatile registers have been preserved.
4008  if (ABI_TOC_REGISTER != 2) {
4009    CHECK_EQ(callee_saved_value, get_register(r2));
4010  }
4011  if (ABI_TOC_REGISTER != 13) {
4012    CHECK_EQ(callee_saved_value, get_register(r13));
4013  }
4014  CHECK_EQ(callee_saved_value, get_register(r14));
4015  CHECK_EQ(callee_saved_value, get_register(r15));
4016  CHECK_EQ(callee_saved_value, get_register(r16));
4017  CHECK_EQ(callee_saved_value, get_register(r17));
4018  CHECK_EQ(callee_saved_value, get_register(r18));
4019  CHECK_EQ(callee_saved_value, get_register(r19));
4020  CHECK_EQ(callee_saved_value, get_register(r20));
4021  CHECK_EQ(callee_saved_value, get_register(r21));
4022  CHECK_EQ(callee_saved_value, get_register(r22));
4023  CHECK_EQ(callee_saved_value, get_register(r23));
4024  CHECK_EQ(callee_saved_value, get_register(r24));
4025  CHECK_EQ(callee_saved_value, get_register(r25));
4026  CHECK_EQ(callee_saved_value, get_register(r26));
4027  CHECK_EQ(callee_saved_value, get_register(r27));
4028  CHECK_EQ(callee_saved_value, get_register(r28));
4029  CHECK_EQ(callee_saved_value, get_register(r29));
4030  CHECK_EQ(callee_saved_value, get_register(r30));
4031  CHECK_EQ(callee_saved_value, get_register(fp));
4032
4033  // Restore non-volatile registers with the original value.
4034  set_register(r2, r2_val);
4035  set_register(r13, r13_val);
4036  set_register(r14, r14_val);
4037  set_register(r15, r15_val);
4038  set_register(r16, r16_val);
4039  set_register(r17, r17_val);
4040  set_register(r18, r18_val);
4041  set_register(r19, r19_val);
4042  set_register(r20, r20_val);
4043  set_register(r21, r21_val);
4044  set_register(r22, r22_val);
4045  set_register(r23, r23_val);
4046  set_register(r24, r24_val);
4047  set_register(r25, r25_val);
4048  set_register(r26, r26_val);
4049  set_register(r27, r27_val);
4050  set_register(r28, r28_val);
4051  set_register(r29, r29_val);
4052  set_register(r30, r30_val);
4053  set_register(fp, r31_val);
4054}
4055
4056
4057intptr_t Simulator::Call(byte* entry, int argument_count, ...) {
4058  va_list parameters;
4059  va_start(parameters, argument_count);
4060  // Set up arguments
4061
4062  // First eight arguments passed in registers r3-r10.
4063  int reg_arg_count = (argument_count > 8) ? 8 : argument_count;
4064  int stack_arg_count = argument_count - reg_arg_count;
4065  for (int i = 0; i < reg_arg_count; i++) {
4066    set_register(i + 3, va_arg(parameters, intptr_t));
4067  }
4068
4069  // Remaining arguments passed on stack.
4070  intptr_t original_stack = get_register(sp);
4071  // Compute position of stack on entry to generated code.
4072  intptr_t entry_stack =
4073      (original_stack -
4074       (kNumRequiredStackFrameSlots + stack_arg_count) * sizeof(intptr_t));
4075  if (base::OS::ActivationFrameAlignment() != 0) {
4076    entry_stack &= -base::OS::ActivationFrameAlignment();
4077  }
4078  // Store remaining arguments on stack, from low to high memory.
4079  // +2 is a hack for the LR slot + old SP on PPC
4080  intptr_t* stack_argument =
4081      reinterpret_cast<intptr_t*>(entry_stack) + kStackFrameExtraParamSlot;
4082  for (int i = 0; i < stack_arg_count; i++) {
4083    stack_argument[i] = va_arg(parameters, intptr_t);
4084  }
4085  va_end(parameters);
4086  set_register(sp, entry_stack);
4087
4088  CallInternal(entry);
4089
4090  // Pop stack passed arguments.
4091  CHECK_EQ(entry_stack, get_register(sp));
4092  set_register(sp, original_stack);
4093
4094  intptr_t result = get_register(r3);
4095  return result;
4096}
4097
4098
4099void Simulator::CallFP(byte* entry, double d0, double d1) {
4100  set_d_register_from_double(1, d0);
4101  set_d_register_from_double(2, d1);
4102  CallInternal(entry);
4103}
4104
4105
4106int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) {
4107  CallFP(entry, d0, d1);
4108  int32_t result = get_register(r3);
4109  return result;
4110}
4111
4112
4113double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
4114  CallFP(entry, d0, d1);
4115  return get_double_from_d_register(1);
4116}
4117
4118
4119uintptr_t Simulator::PushAddress(uintptr_t address) {
4120  uintptr_t new_sp = get_register(sp) - sizeof(uintptr_t);
4121  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
4122  *stack_slot = address;
4123  set_register(sp, new_sp);
4124  return new_sp;
4125}
4126
4127
4128uintptr_t Simulator::PopAddress() {
4129  uintptr_t current_sp = get_register(sp);
4130  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
4131  uintptr_t address = *stack_slot;
4132  set_register(sp, current_sp + sizeof(uintptr_t));
4133  return address;
4134}
4135}  // namespace internal
4136}  // namespace v8
4137
4138#endif  // USE_SIMULATOR
4139#endif  // V8_TARGET_ARCH_PPC
4140