Home | History | Annotate | Download | only in ppc
      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.
     23 namespace v8 {
     24 namespace internal {
     25 
     26 const 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.
     36 class 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 
     67 PPCDebugger::~PPCDebugger() {}
     68 
     69 
     70 #ifdef GENERATED_CODE_COVERAGE
     71 static FILE* coverage_log = NULL;
     72 
     73 
     74 static 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 
     82 void 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 
    110 static void InitializeCoverage() {}
    111 
    112 
    113 void 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 
    136 intptr_t PPCDebugger::GetRegisterValue(int regnum) {
    137   return sim_->get_register(regnum);
    138 }
    139 
    140 
    141 double PPCDebugger::GetRegisterPairDoubleValue(int regnum) {
    142   return sim_->get_double_from_register_pair(regnum);
    143 }
    144 
    145 
    146 double PPCDebugger::GetFPDoubleRegisterValue(int regnum) {
    147   return sim_->get_double_from_d_register(regnum);
    148 }
    149 
    150 
    151 bool 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 
    169 bool 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 
    179 bool 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 
    194 bool 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 
    205 void PPCDebugger::UndoBreakpoints() {
    206   if (sim_->break_pc_ != NULL) {
    207     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    208   }
    209 }
    210 
    211 
    212 void PPCDebugger::RedoBreakpoints() {
    213   if (sim_->break_pc_ != NULL) {
    214     sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
    215   }
    216 }
    217 
    218 
    219 void 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 
    687 static 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 
    694 static uint32_t ICacheHash(void* key) {
    695   return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
    696 }
    697 
    698 
    699 static 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 
    706 void Simulator::set_last_debugger_input(char* input) {
    707   DeleteArray(last_debugger_input_);
    708   last_debugger_input_ = input;
    709 }
    710 
    711 
    712 void 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 
    734 CachePage* 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.
    745 void 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 
    757 void 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 
    779 void 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 
    787 Simulator::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 
    835 Simulator::~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.
    845 class 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
    926 void 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 
    938 void* 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.
    947 Simulator* 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.
    963 void 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.
    970 intptr_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 
    980 double 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.
    996 void Simulator::set_pc(intptr_t value) {
    997   pc_modified_ = true;
    998   special_reg_pc_ = value;
    999 }
   1000 
   1001 
   1002 bool 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.
   1008 intptr_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.
   1015 void 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.
   1023 void Simulator::SetFpResult(const double& result) {
   1024   set_d_register_from_double(1, result);
   1025 }
   1026 
   1027 
   1028 void 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 
   1038 uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) {
   1039   uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
   1040   return *ptr;
   1041 }
   1042 
   1043 
   1044 int32_t Simulator::ReadW(intptr_t addr, Instruction* instr) {
   1045   int32_t* ptr = reinterpret_cast<int32_t*>(addr);
   1046   return *ptr;
   1047 }
   1048 
   1049 
   1050 void 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 
   1057 void 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 
   1064 uint16_t Simulator::ReadHU(intptr_t addr, Instruction* instr) {
   1065   uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1066   return *ptr;
   1067 }
   1068 
   1069 
   1070 int16_t Simulator::ReadH(intptr_t addr, Instruction* instr) {
   1071   int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1072   return *ptr;
   1073 }
   1074 
   1075 
   1076 void 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 
   1083 void 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 
   1090 uint8_t Simulator::ReadBU(intptr_t addr) {
   1091   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1092   return *ptr;
   1093 }
   1094 
   1095 
   1096 int8_t Simulator::ReadB(intptr_t addr) {
   1097   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1098   return *ptr;
   1099 }
   1100 
   1101 
   1102 void Simulator::WriteB(intptr_t addr, uint8_t value) {
   1103   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1104   *ptr = value;
   1105 }
   1106 
   1107 
   1108 void Simulator::WriteB(intptr_t addr, int8_t value) {
   1109   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1110   *ptr = value;
   1111 }
   1112 
   1113 
   1114 intptr_t* Simulator::ReadDW(intptr_t addr) {
   1115   intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
   1116   return ptr;
   1117 }
   1118 
   1119 
   1120 void 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.
   1128 uintptr_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.
   1142 void 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.
   1150 bool 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.
   1161 bool 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.
   1170 bool 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
   1191 static 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
   1196 static 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.
   1208 typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
   1209                                          intptr_t arg2, intptr_t arg3,
   1210                                          intptr_t arg4, intptr_t arg5);
   1211 typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1,
   1212                                                intptr_t arg2, intptr_t arg3,
   1213                                                intptr_t arg4, intptr_t arg5);
   1214 typedef 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.
   1220 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
   1221 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
   1222 typedef double (*SimulatorRuntimeFPCall)(double darg0);
   1223 typedef 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).
   1227 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0);
   1228 typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1);
   1229 
   1230 // This signature supports direct call to accessor getter callback.
   1231 typedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1);
   1232 typedef 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.
   1237 void 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.
   1529 bool Simulator::isStopInstruction(Instruction* instr) {
   1530   return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
   1531 }
   1532 
   1533 
   1534 bool Simulator::isWatchedStop(uint32_t code) {
   1535   DCHECK(code <= kMaxStopCode);
   1536   return code < kNumOfWatchedStops;
   1537 }
   1538 
   1539 
   1540 bool 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 
   1548 void Simulator::EnableStop(uint32_t code) {
   1549   DCHECK(isWatchedStop(code));
   1550   if (!isEnabledStop(code)) {
   1551     watched_stops_[code].count &= ~kStopDisabledBit;
   1552   }
   1553 }
   1554 
   1555 
   1556 void Simulator::DisableStop(uint32_t code) {
   1557   DCHECK(isWatchedStop(code));
   1558   if (isEnabledStop(code)) {
   1559     watched_stops_[code].count |= kStopDisabledBit;
   1560   }
   1561 }
   1562 
   1563 
   1564 void 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.
   1581 void 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 
   1602 void 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 
   1620 void 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.
   1674 void 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 
   1727 bool 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 
   1971 bool 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 
   2230 bool 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 
   2749 void 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 
   2772 void 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 
   2782 void 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 
   2808 void 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
   3233 void 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 
   3348 void 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 
   3871 void 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.
   3883 void 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 
   3903 void 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 
   3935 void 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 
   4057 intptr_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 
   4099 void 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 
   4106 int32_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 
   4113 double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
   4114   CallFP(entry, d0, d1);
   4115   return get_double_from_d_register(1);
   4116 }
   4117 
   4118 
   4119 uintptr_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 
   4128 uintptr_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