1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <stdarg.h> 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <stdlib.h> 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <cmath> 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/assembler.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/bits.h" 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/codegen.h" 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/disasm.h" 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ppc/constants-ppc.h" 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ppc/frames-ppc.h" 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ppc/simulator-ppc.h" 18342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/runtime/runtime-utils.h" 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if defined(USE_SIMULATOR) 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Only build the simulator if not compiling for real PPC hardware. 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochconst auto GetRegConfig = RegisterConfiguration::Crankshaft; 2721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// This macro provides a platform independent use of sscanf. The reason for 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// SScanF not being implemented in a platform independent way through 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// ::v8::internal::OS in the same way as SNPrintF is that the 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Windows C Run-Time Library does not provide vsscanf. 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define SScanF sscanf // NOLINT 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The PPCDebugger class is used by the simulator while debugging simulated 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// PowerPC code. 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass PPCDebugger { 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit PPCDebugger(Simulator* sim) : sim_(sim) {} 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~PPCDebugger(); 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Stop(Instruction* instr); 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Debug(); 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const Instr kBreakpointInstr = (TWI | 0x1f * B21); 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const Instr kNopInstr = (ORI); // ori, 0,0,0 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Simulator* sim_; 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t GetRegisterValue(int regnum); 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double GetRegisterPairDoubleValue(int regnum); 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double GetFPDoubleRegisterValue(int regnum); 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GetValue(const char* desc, intptr_t* value); 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GetFPDoubleValue(const char* desc, double* value); 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Set or delete a breakpoint. Returns true if successful. 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool SetBreakpoint(Instruction* break_pc); 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool DeleteBreakpoint(Instruction* break_pc); 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Undo and redo all breakpoints. This is needed to bracket disassembly and 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // execution to skip past breakpoints when run from the debugger. 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void UndoBreakpoints(); 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RedoBreakpoints(); 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPPCDebugger::~PPCDebugger() {} 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifdef GENERATED_CODE_COVERAGE 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic FILE* coverage_log = NULL; 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void InitializeCoverage() { 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (file_name != NULL) { 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier coverage_log = fopen(file_name, "aw+"); 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PPCDebugger::Stop(Instruction* instr) { 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get the stop code. 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t code = instr->SvcValue() & kStopCodeMask; 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Retrieve the encoded address, which comes just after this stop. 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char** msg_address = 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize); 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* msg = *msg_address; 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(msg != NULL); 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Update this stop description. 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isWatchedStop(code) && !watched_stops_[code].desc) { 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier watched_stops_[code].desc = msg; 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strlen(msg) > 0) { 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (coverage_log != NULL) { 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fprintf(coverage_log, "%s\n", msg); 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fflush(coverage_log); 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Overwrite the instruction and address with nops. 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instr->SetInstructionBits(kNopInstr); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else // ndef GENERATED_CODE_COVERAGE 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void InitializeCoverage() {} 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PPCDebugger::Stop(Instruction* instr) { 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get the stop code. 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // use of kStopCodeMask not right on PowerPC 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t code = instr->SvcValue() & kStopCodeMask; 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Retrieve the encoded address, which comes just after this stop. 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* msg = 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize); 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Update this stop description. 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) { 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->watched_stops_[code].desc = msg; 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Print the stop message and code if it is not the default code. 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (code != kMaxStopCode) { 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Simulator hit stop %u: %s\n", code, msg); 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Simulator hit %s\n", msg); 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Debug(); 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierintptr_t PPCDebugger::GetRegisterValue(int regnum) { 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return sim_->get_register(regnum); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierdouble PPCDebugger::GetRegisterPairDoubleValue(int regnum) { 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return sim_->get_double_from_register_pair(regnum); 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierdouble PPCDebugger::GetFPDoubleRegisterValue(int regnum) { 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return sim_->get_double_from_d_register(regnum); 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool PPCDebugger::GetValue(const char* desc, intptr_t* value) { 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int regnum = Registers::Number(desc); 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (regnum != kNoRegister) { 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *value = GetRegisterValue(regnum); 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strncmp(desc, "0x", 2) == 0) { 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return SScanF(desc + 2, "%" V8PRIxPTR, 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<uintptr_t*>(value)) == 1; 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return SScanF(desc, "%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) == 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1; 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool PPCDebugger::GetFPDoubleValue(const char* desc, double* value) { 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int regnum = DoubleRegisters::Number(desc); 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (regnum != kNoRegister) { 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *value = sim_->get_double_from_d_register(regnum); 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool PPCDebugger::SetBreakpoint(Instruction* break_pc) { 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if a breakpoint can be set. If not return without any side-effects. 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim_->break_pc_ != NULL) { 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Set the breakpoint. 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_pc_ = break_pc; 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_instr_ = break_pc->InstructionBits(); 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Not setting the breakpoint instruction in the code itself. It will be set 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // when the debugger shell continues. 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool PPCDebugger::DeleteBreakpoint(Instruction* break_pc) { 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim_->break_pc_ != NULL) { 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_pc_ = NULL; 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_instr_ = 0; 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PPCDebugger::UndoBreakpoints() { 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim_->break_pc_ != NULL) { 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PPCDebugger::RedoBreakpoints() { 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim_->break_pc_ != NULL) { 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->break_pc_->SetInstructionBits(kBreakpointInstr); 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PPCDebugger::Debug() { 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t last_pc = -1; 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool done = false; 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define COMMAND_SIZE 63 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ARG_SIZE 255 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define STR(a) #a 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define XSTR(a) STR(a) 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char cmd[COMMAND_SIZE + 1]; 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char arg1[ARG_SIZE + 1]; 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char arg2[ARG_SIZE + 1]; 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* argv[3] = {cmd, arg1, arg2}; 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // make sure to have a proper terminating character if reaching the limit 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cmd[COMMAND_SIZE] = 0; 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arg1[ARG_SIZE] = 0; 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arg2[ARG_SIZE] = 0; 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Undo all set breakpoints while running in the debugger shell. This will 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // make them invisible to all commands. 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UndoBreakpoints(); 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Disable tracing while simulating 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool trace = ::v8::internal::FLAG_trace_sim; 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ::v8::internal::FLAG_trace_sim = false; 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (!done && !sim_->has_bad_pc()) { 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (last_pc != sim_->get_pc()) { 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::NameConverter converter; 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::Disassembler dasm(converter); 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // use a reasonably large buffer 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::internal::EmbeddedVector<char, 256> buffer; 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc())); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), buffer.start()); 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_pc = sim_->get_pc(); 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* line = ReadLine("sim> "); 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (line == NULL) { 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* last_input = sim_->last_debugger_input(); 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(line, "\n") == 0 && last_input != NULL) { 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier line = last_input; 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Ownership is transferred to sim_; 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->set_last_debugger_input(line); 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Use sscanf to parse the individual parts of the command line. At the 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // moment no command expects more than two parameters. 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int argc = SScanF(line, 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "%" XSTR(COMMAND_SIZE) "s " 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "%" XSTR(ARG_SIZE) "s " 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "%" XSTR(ARG_SIZE) "s", 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cmd, arg1, arg2); 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If at a breakpoint, proceed past it. 278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((reinterpret_cast<Instruction*>(sim_->get_pc())) 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->InstructionBits() == 0x7d821008) { 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize); 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->ExecuteInstruction( 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Instruction*>(sim_->get_pc())); 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argc == 2 && last_pc != sim_->get_pc() && GetValue(arg1, &value)) { 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 1; i < value; i++) { 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::NameConverter converter; 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::Disassembler dasm(converter); 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // use a reasonably large buffer 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::internal::EmbeddedVector<char, 256> buffer; 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dasm.InstructionDecode(buffer, 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<byte*>(sim_->get_pc())); 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer.start()); 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->ExecuteInstruction( 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Instruction*>(sim_->get_pc())); 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If at a breakpoint, proceed past it. 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((reinterpret_cast<Instruction*>(sim_->get_pc())) 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->InstructionBits() == 0x7d821008) { 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize); 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Execute the one instruction we broke at with breakpoints disabled. 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->ExecuteInstruction( 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Instruction*>(sim_->get_pc())); 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Leave the debugger shell. 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier done = true; 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) { 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double dvalue; 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(arg1, "all") == 0) { 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < kNumRegisters; i++) { 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = GetRegisterValue(i); 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF(" %3s: %08" V8PRIxPTR, 32021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetGeneralRegisterName(i), value); 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (i % 2) == 0) { 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dvalue = GetRegisterPairDoubleValue(i); 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" (%f)\n", dvalue); 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (i != 0 && !((i + 1) & 3)) { 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" pc: %08" V8PRIxPTR " lr: %08" V8PRIxPTR 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " " 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "ctr: %08" V8PRIxPTR " xer: %08x cr: %08x\n", 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->special_reg_pc_, sim_->special_reg_lr_, 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->special_reg_ctr_, sim_->special_reg_xer_, 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->condition_reg_); 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(arg1, "alld") == 0) { 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < kNumRegisters; i++) { 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = GetRegisterValue(i); 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR, 33921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetGeneralRegisterName(i), value, value); 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (i % 2) == 0) { 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dvalue = GetRegisterPairDoubleValue(i); 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" (%f)\n", dvalue); 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (!((i + 1) % 2)) { 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" pc: %08" V8PRIxPTR " lr: %08" V8PRIxPTR 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " " 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "ctr: %08" V8PRIxPTR " xer: %08x cr: %08x\n", 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->special_reg_pc_, sim_->special_reg_lr_, 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->special_reg_ctr_, sim_->special_reg_xer_, 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->condition_reg_); 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(arg1, "allf") == 0) { 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < DoubleRegister::kNumRegisters; i++) { 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dvalue = GetFPDoubleRegisterValue(i); 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint64_t as_words = bit_cast<uint64_t>(dvalue); 358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("%3s: %f 0x%08x %08x\n", 35921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetDoubleRegisterName(i), dvalue, 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(as_words >> 32), 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(as_words & 0xffffffff)); 362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (arg1[0] == 'r' && 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (arg1[1] >= '0' && arg1[1] <= '9' && 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (arg1[2] == '\0' || (arg1[2] >= '0' && arg1[2] <= '9' && 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arg1[3] == '\0')))) { 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int regnum = strtoul(&arg1[1], 0, 10); 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (regnum != kNoRegister) { 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = GetRegisterValue(regnum); 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value, 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value); 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s unrecognized\n", arg1); 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (GetValue(arg1, &value)) { 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value, 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value); 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (GetFPDoubleValue(arg1, &dvalue)) { 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint64_t as_words = bit_cast<uint64_t>(dvalue); 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s: %f 0x%08x %08x\n", arg1, dvalue, 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(as_words >> 32), 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(as_words & 0xffffffff)); 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s unrecognized\n", arg1); 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("print <register>\n"); 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if ((strcmp(cmd, "po") == 0) || 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (strcmp(cmd, "printobject") == 0)) { 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argc == 2) { 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OFStream os(stdout); 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (GetValue(arg1, &value)) { 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* obj = reinterpret_cast<Object*>(value); 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << arg1 << ": \n"; 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifdef DEBUG 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier obj->Print(os); 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << "\n"; 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << Brief(obj) << "\n"; 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << arg1 << " unrecognized\n"; 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("printobject <value>\n"); 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "setpc") == 0) { 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!GetValue(arg1, &value)) { 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s unrecognized\n", arg1); 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->set_pc(value); 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) { 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* cur = NULL; 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* end = NULL; 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int next_arg = 1; 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(cmd, "stack") == 0) { 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur = reinterpret_cast<intptr_t*>(sim_->get_register(Simulator::sp)); 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { // "mem" 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!GetValue(arg1, &value)) { 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s unrecognized\n", arg1); 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur = reinterpret_cast<intptr_t*>(value); 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_arg++; 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t words; // likely inaccurate variable name for 64bit 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argc == next_arg) { 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier words = 10; 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!GetValue(argv[next_arg], &words)) { 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier words = 10; 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end = cur + words; 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (cur < end) { 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" 0x%08" V8PRIxPTR ": 0x%08" V8PRIxPTR " %10" V8PRIdPTR, 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<intptr_t>(cur), *cur, *cur); 449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value = *cur; 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Heap* current_heap = sim_->isolate_->heap(); 452342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (((value & 1) == 0) || 453342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch current_heap->ContainsSlow(obj->address())) { 454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" ("); 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((value & 1) == 0) { 456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("smi %d", PlatformSmiTagging::SmiToInt(obj)); 457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier obj->ShortPrint(); 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(")"); 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur++; 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) { 466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::NameConverter converter; 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::Disassembler dasm(converter); 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // use a reasonably large buffer 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::internal::EmbeddedVector<char, 256> buffer; 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier byte* prev = NULL; 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier byte* cur = NULL; 473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier byte* end = NULL; 474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argc == 1) { 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur = reinterpret_cast<byte*>(sim_->get_pc()); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end = cur + (10 * Instruction::kInstrSize); 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (argc == 2) { 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int regnum = Registers::Number(arg1); 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) { 481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The argument is an address or a register name. 482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (GetValue(arg1, &value)) { 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur = reinterpret_cast<byte*>(value); 485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Disassemble 10 instructions at <arg1>. 486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end = cur + (10 * Instruction::kInstrSize); 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The argument is the number of instructions. 490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (GetValue(arg1, &value)) { 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur = reinterpret_cast<byte*>(sim_->get_pc()); 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Disassemble <arg1> instructions. 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end = cur + (value * Instruction::kInstrSize); 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value1; 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value2; 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur = reinterpret_cast<byte*>(value1); 502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end = cur + (value2 * Instruction::kInstrSize); 503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (cur < end) { 507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier prev = cur; 508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur += dasm.InstructionDecode(buffer, cur); 509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" 0x%08" V8PRIxPTR " %s\n", reinterpret_cast<intptr_t>(prev), 510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer.start()); 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "gdb") == 0) { 513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("relinquishing control to gdb\n"); 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::base::OS::DebugBreak(); 515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("regaining control from gdb\n"); 516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "break") == 0) { 517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argc == 2) { 518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (GetValue(arg1, &value)) { 520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) { 521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("setting breakpoint failed\n"); 522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%s unrecognized\n", arg1); 525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("break <address>\n"); 528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "del") == 0) { 530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!DeleteBreakpoint(NULL)) { 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("deleting breakpoint failed\n"); 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "cr") == 0) { 534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Condition reg: %08x\n", sim_->condition_reg_); 535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "lr") == 0) { 536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Link reg: %08" V8PRIxPTR "\n", sim_->special_reg_lr_); 537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "ctr") == 0) { 538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Ctr reg: %08" V8PRIxPTR "\n", sim_->special_reg_ctr_); 539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "xer") == 0) { 540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("XER: %08x\n", sim_->special_reg_xer_); 541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "fpscr") == 0) { 542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("FPSCR: %08x\n", sim_->fp_condition_reg_); 543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(cmd, "stop") == 0) { 544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t value; 545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t stop_pc = 546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->get_pc() - (Instruction::kInstrSize + kPointerSize); 547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc); 548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* msg_address = 549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize); 550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) { 551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Remove the current stop. 552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim_->isStopInstruction(stop_instr)) { 553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier stop_instr->SetInstructionBits(kNopInstr); 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier msg_address->SetInstructionBits(kNopInstr); 555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Not at debugger stop.\n"); 557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (argc == 3) { 559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Print information about all/the specified breakpoint(s). 560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(arg1, "info") == 0) { 561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(arg2, "all") == 0) { 562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Stop information:\n"); 563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) { 564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->PrintStopInfo(i); 565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (GetValue(arg2, &value)) { 567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->PrintStopInfo(value); 568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Unrecognized argument.\n"); 570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(arg1, "enable") == 0) { 572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Enable all/the specified breakpoint(s). 573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(arg2, "all") == 0) { 574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) { 575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->EnableStop(i); 576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (GetValue(arg2, &value)) { 578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->EnableStop(value); 579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Unrecognized argument.\n"); 581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (strcmp(arg1, "disable") == 0) { 583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Disable all/the specified breakpoint(s). 584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (strcmp(arg2, "all") == 0) { 585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) { 586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->DisableStop(i); 587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (GetValue(arg2, &value)) { 589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim_->DisableStop(value); 590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Unrecognized argument.\n"); 592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Wrong usage. Use help command for more information.\n"); 596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) { 598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim; 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Trace of executed instructions is %s\n", 600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ::v8::internal::FLAG_trace_sim ? "on" : "off"); 601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { 602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("cont\n"); 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" continue execution (alias 'c')\n"); 604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("stepi [num instructions]\n"); 605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" step one/num instruction(s) (alias 'si')\n"); 606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("print <register>\n"); 607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print register content (alias 'p')\n"); 608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" use register name 'all' to display all integer registers\n"); 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF( 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " use register name 'alld' to display integer registers " 611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "with decimal values\n"); 612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" use register name 'rN' to display register number 'N'\n"); 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" add argument 'fp' to print register pair double values\n"); 614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF( 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " use register name 'allf' to display floating-point " 616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "registers\n"); 617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("printobject <register>\n"); 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print an object from a register (alias 'po')\n"); 619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("cr\n"); 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print condition register\n"); 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("lr\n"); 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print link register\n"); 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("ctr\n"); 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print ctr register\n"); 625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("xer\n"); 626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print XER\n"); 627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("fpscr\n"); 628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" print FPSCR\n"); 629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("stack [<num words>]\n"); 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" dump stack content, default dump 10 words)\n"); 631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("mem <address> [<num words>]\n"); 632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" dump memory content, default dump 10 words)\n"); 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("disasm [<instructions>]\n"); 634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("disasm [<address/register>]\n"); 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("disasm [[<address/register>] <instructions>]\n"); 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" disassemble code, default is 10 instructions\n"); 637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" from pc (alias 'di')\n"); 638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("gdb\n"); 639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" enter gdb\n"); 640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("break <address>\n"); 641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" set a break point on the address\n"); 642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("del\n"); 643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" delete the breakpoint\n"); 644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("trace (alias 't')\n"); 645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" toogle the tracing of all executed statements\n"); 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("stop feature:\n"); 647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" Description:\n"); 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" Stops are debug instructions inserted by\n"); 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" the Assembler::stop() function.\n"); 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" When hitting a stop, the Simulator will\n"); 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" stop and and give control to the PPCDebugger.\n"); 652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" The first %d stop codes are watched:\n", 653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Simulator::kNumOfWatchedStops); 654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" - They can be enabled / disabled: the Simulator\n"); 655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" will / won't stop when hitting them.\n"); 656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" - The Simulator keeps track of how many times they \n"); 657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" are met. (See the info command.) Going over a\n"); 658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" disabled stop still increases its counter. \n"); 659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" Commands:\n"); 660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" stop info all/<code> : print infos about number <code>\n"); 661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" or all stop(s).\n"); 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" stop enable/disable all/<code> : enables / disables\n"); 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" all or number <code> stop(s)\n"); 664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" stop unstop\n"); 665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" ignore the stop instruction at the current location\n"); 666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" from now on\n"); 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Unknown command: %s\n", cmd); 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Add all the breakpoints back to stop execution and enter the debugger 674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // shell when hit. 675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RedoBreakpoints(); 676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Restore tracing 677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ::v8::internal::FLAG_trace_sim = trace; 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef COMMAND_SIZE 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef ARG_SIZE 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef STR 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef XSTR 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool ICacheMatch(void* one, void* two) { 688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0); 689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return one == two; 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic uint32_t ICacheHash(void* key) { 695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; 696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool AllOnOnePage(uintptr_t start, int size) { 700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t start_page = (start & ~CachePage::kPageMask); 701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t end_page = ((start + size) & ~CachePage::kPageMask); 702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return start_page == end_page; 703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::set_last_debugger_input(char* input) { 707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DeleteArray(last_debugger_input_); 708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_debugger_input_ = input; 709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 71221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Simulator::FlushICache(base::HashMap* i_cache, void* start_addr, 713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t size) { 714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t start = reinterpret_cast<intptr_t>(start_addr); 715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int intra_line = (start & CachePage::kLineMask); 716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier start -= intra_line; 717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size += intra_line; 718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size = ((size - 1) | CachePage::kLineMask) + 1; 719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = (start & CachePage::kPageMask); 720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (!AllOnOnePage(start, size - 1)) { 721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bytes_to_flush = CachePage::kPageSize - offset; 722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlushOnePage(i_cache, start, bytes_to_flush); 723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier start += bytes_to_flush; 724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size -= bytes_to_flush; 725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask)); 726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier offset = 0; 727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (size != 0) { 729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlushOnePage(i_cache, start, size); 730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 73421efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochCachePage* Simulator::GetCachePage(base::HashMap* i_cache, void* page) { 73521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page)); 736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (entry->value == NULL) { 737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CachePage* new_page = new CachePage(); 738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier entry->value = new_page; 739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<CachePage*>(entry->value); 741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Flush from start up to and not including start + size. 74521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Simulator::FlushOnePage(base::HashMap* i_cache, intptr_t start, int size) { 746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(size <= CachePage::kPageSize); 747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(AllOnOnePage(start, size - 1)); 748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((start & CachePage::kLineMask) == 0); 749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((size & CachePage::kLineMask) == 0); 750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); 751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = (start & CachePage::kPageMask); 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CachePage* cache_page = GetCachePage(i_cache, page); 753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* valid_bytemap = cache_page->ValidityByte(offset); 754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); 755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 75721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Simulator::CheckICache(base::HashMap* i_cache, Instruction* instr) { 758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t address = reinterpret_cast<intptr_t>(instr); 759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); 760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); 761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = (address & CachePage::kPageMask); 762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CachePage* cache_page = GetCachePage(i_cache, page); 763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* cache_valid_byte = cache_page->ValidityByte(offset); 764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); 765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); 766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (cache_hit) { 767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the data in memory matches the contents of the I-cache. 768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(0, 769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier memcmp(reinterpret_cast<void*>(instr), 770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cache_page->CachedData(offset), Instruction::kInstrSize)); 771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Cache miss. Load memory into the cache. 773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier memcpy(cached_line, line, CachePage::kLineLength); 774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *cache_valid_byte = CachePage::LINE_VALID; 775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::Initialize(Isolate* isolate) { 780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isolate->simulator_initialized()) return; 781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->set_simulator_initialized(true); 782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ::v8::internal::ExternalReference::set_redirector(isolate, 783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &RedirectExternalReference); 784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierSimulator::Simulator(Isolate* isolate) : isolate_(isolate) { 788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i_cache_ = isolate_->simulator_i_cache(); 789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (i_cache_ == NULL) { 79021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch i_cache_ = new base::HashMap(&ICacheMatch); 791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate_->set_simulator_i_cache(i_cache_); 792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Initialize(isolate); 794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Set up simulator support first. Some of this information is needed to 795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// setup the architecture state. 796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t stack_size = FLAG_sim_stack_size * KB; 798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t stack_size = MB; // allocate 1MB for stack 800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_size += 2 * stack_protection_size_; 802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier stack_ = reinterpret_cast<char*>(malloc(stack_size)); 803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pc_modified_ = false; 804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier icount_ = 0; 805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break_pc_ = NULL; 806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break_instr_ = 0; 807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Set up architecture state. 809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // All registers are initialized to zero to start with. 810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < kNumGPRs; i++) { 811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier registers_[i] = 0; 812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = 0; 814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fp_condition_reg_ = 0; 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_pc_ = 0; 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_lr_ = 0; 817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_ctr_ = 0; 818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Initializing FP registers. 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < kNumFPRs; i++) { 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fp_registers_[i] = 0.0; 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The sp is initialized to point to the bottom (high address) of the 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // allocated stack area. To be safe in potential stack underflows we leave 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // some buffer below. 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch registers_[sp] = 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<intptr_t>(stack_) + stack_size - stack_protection_size_; 829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InitializeCoverage(); 830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_debugger_input_ = NULL; 832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSimulator::~Simulator() { free(stack_); } 836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// When the generated code calls an external reference we need to catch that in 839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the simulator. The external reference will be a function compiled for the 840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// host architecture. We need to call that function instead of trying to 841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// execute it with the simulator. We do that by redirecting the external 842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// reference to a svc (Supervisor Call) instruction that is handled by 843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the simulator. We write the original destination of the jump just at a known 844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// offset from the svc instruction so the simulator knows what to call. 845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass Redirection { 846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Redirection(Isolate* isolate, void* external_function, 848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference::Type type) 849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : external_function_(external_function), 850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier swi_instruction_(rtCallRedirInstr | kCallRtRedirected), 851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier type_(type), 852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_(NULL) { 853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_ = isolate->simulator_redirection(); 854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Simulator::current(isolate)->FlushICache( 855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->simulator_i_cache(), 856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<void*>(&swi_instruction_), Instruction::kInstrSize); 857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->set_simulator_redirection(this); 858342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_USES_FUNCTION_DESCRIPTORS) { 859342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch function_descriptor_[0] = reinterpret_cast<intptr_t>(&swi_instruction_); 860342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch function_descriptor_[1] = 0; 861342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch function_descriptor_[2] = 0; 862342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 865342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch void* address() { 866342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_USES_FUNCTION_DESCRIPTORS) { 867342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return reinterpret_cast<void*>(function_descriptor_); 868342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } else { 869342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return reinterpret_cast<void*>(&swi_instruction_); 870342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void* external_function() { return external_function_; } 874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference::Type type() { return type_; } 875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Redirection* Get(Isolate* isolate, void* external_function, 877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference::Type type) { 878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Redirection* current = isolate->simulator_redirection(); 879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; current != NULL; current = current->next_) { 880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current->external_function_ == external_function) { 881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(current->type(), type); 882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return current; 883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new Redirection(isolate, external_function, type); 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Redirection* FromSwiInstruction(Instruction* swi_instruction) { 889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* addr_of_redirection = 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addr_of_swi - offsetof(Redirection, swi_instruction_); 892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Redirection*>(addr_of_redirection); 893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 895342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch static Redirection* FromAddress(void* address) { 896342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int delta = ABI_USES_FUNCTION_DESCRIPTORS 897342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ? offsetof(Redirection, function_descriptor_) 898342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch : offsetof(Redirection, swi_instruction_); 899342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch char* addr_of_redirection = reinterpret_cast<char*>(address) - delta; 900342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return reinterpret_cast<Redirection*>(addr_of_redirection); 901342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 902342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void* ReverseRedirection(intptr_t reg) { 904342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Redirection* redirection = FromAddress(reinterpret_cast<void*>(reg)); 905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return redirection->external_function(); 906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteChain(Redirection* redirection) { 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (redirection != nullptr) { 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Redirection* next = redirection->next_; 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch delete redirection; 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch redirection = next; 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void* external_function_; 918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t swi_instruction_; 919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference::Type type_; 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Redirection* next_; 921342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t function_descriptor_[3]; 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static 92621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Simulator::TearDown(base::HashMap* i_cache, Redirection* first) { 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Redirection::DeleteChain(first); 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i_cache != nullptr) { 92921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr; 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch entry = i_cache->Next(entry)) { 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch delete static_cast<CachePage*>(entry->value); 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch delete i_cache; 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid* Simulator::RedirectExternalReference(Isolate* isolate, 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void* external_function, 940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference::Type type) { 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Redirection* redirection = Redirection::Get(isolate, external_function, type); 942342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return redirection->address(); 943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Get the active Simulator for the current thread. 947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierSimulator* Simulator::current(Isolate* isolate) { 948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::internal::Isolate::PerIsolateThreadData* isolate_data = 949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->FindOrAllocatePerThreadDataForThisThread(); 950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(isolate_data != NULL); 951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Simulator* sim = isolate_data->simulator(); 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sim == NULL) { 954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(146): delete the simulator object when a thread/isolate goes away. 955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sim = new Simulator(isolate); 956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate_data->set_simulator(sim); 957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return sim; 959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Sets the register in the architecture state. 963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::set_register(int reg, intptr_t value) { 964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((reg >= 0) && (reg < kNumGPRs)); 965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier registers_[reg] = value; 966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Get the register from the architecture state. 970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierintptr_t Simulator::get_register(int reg) const { 971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((reg >= 0) && (reg < kNumGPRs)); 972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Stupid code added to avoid bug in GCC. 973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949 974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reg >= kNumGPRs) return 0; 975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // End stupid code. 976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return registers_[reg]; 977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierdouble Simulator::get_double_from_register_pair(int reg) { 981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((reg >= 0) && (reg < kNumGPRs) && ((reg % 2) == 0)); 982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double dm_val = 0.0; 984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if !V8_TARGET_ARCH_PPC64 // doesn't make sense in 64bit mode 985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Read the bits from the unsigned integer register_[] array 986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // into the double precision floating point value and return it. 987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char buffer[sizeof(fp_registers_[0])]; 988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); 989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); 990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (dm_val); 992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Raw access to the PC register. 996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::set_pc(intptr_t value) { 997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pc_modified_ = true; 998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_pc_ = value; 999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::has_bad_pc() const { 1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc)); 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Raw access to the PC register without the special adjustment when reading. 1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierintptr_t Simulator::get_pc() const { return special_reg_pc_; } 1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Runtime FP routines take: 1012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - two double arguments 1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - one double argument and zero or one integer arguments. 1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// All are consructed here from d1, d2 and r3. 1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::GetFpArgs(double* x, double* y, intptr_t* z) { 1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *x = get_double_from_d_register(1); 1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *y = get_double_from_d_register(2); 1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *z = get_register(3); 1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The return value is in d1. 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Simulator::SetFpResult(const double& result) { 1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(1, result); 1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::TrashCallerSaveRegisters() { 1029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// We don't trash the registers with the return value. 1030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if 0 // A good idea to trash volatile registers, needs to be done 1031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier registers_[2] = 0x50Bad4U; 1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier registers_[3] = 0x50Bad4U; 1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier registers_[12] = 0x50Bad4U; 1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernieruint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) { 1039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 1040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *ptr; 1041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint32_t Simulator::ReadW(intptr_t addr, Instruction* instr) { 1045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t* ptr = reinterpret_cast<int32_t*>(addr); 1046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *ptr; 1047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1049958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteW(intptr_t addr, uint32_t value, Instruction* instr) { 1051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 1052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteW(intptr_t addr, int32_t value, Instruction* instr) { 1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t* ptr = reinterpret_cast<int32_t*>(addr); 1059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernieruint16_t Simulator::ReadHU(intptr_t addr, Instruction* instr) { 1065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *ptr; 1067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint16_t Simulator::ReadH(intptr_t addr, Instruction* instr) { 1071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *ptr; 1073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteH(intptr_t addr, uint16_t value, Instruction* instr) { 1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteH(intptr_t addr, int16_t value, Instruction* instr) { 1084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1088958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernieruint8_t Simulator::ReadBU(intptr_t addr) { 1091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *ptr; 1093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint8_t Simulator::ReadB(intptr_t addr) { 1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *ptr; 1099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteB(intptr_t addr, uint8_t value) { 1103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteB(intptr_t addr, int8_t value) { 1109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierintptr_t* Simulator::ReadDW(intptr_t addr) { 1115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ptr; 1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::WriteDW(intptr_t addr, int64_t value) { 1121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t* ptr = reinterpret_cast<int64_t*>(addr); 1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *ptr = value; 1123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Returns the limit of the stack area to enable checking for stack overflows. 1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuintptr_t Simulator::StackLimit(uintptr_t c_limit) const { 1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The simulator uses a separate JS stack. If we have exhausted the C stack, 1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // we also drop down the JS limit to reflect the exhaustion on the JS stack. 1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (GetCurrentStackPosition() < c_limit) { 1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<uintptr_t>(get_sp()); 1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise the limit is the JS stack. Leave a safety margin to prevent 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // overrunning the stack when pushing values. 1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<uintptr_t>(stack_) + stack_protection_size_; 1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Unsupported instructions use Format to print an error and stop execution. 1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::Format(Instruction* instr, const char* format) { 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR ": %s\n", 1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<intptr_t>(instr), format); 1145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Calculate C flag value for additions. 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) { 1151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t uleft = static_cast<uint32_t>(left); 1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t uright = static_cast<uint32_t>(right); 1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t urest = 0xffffffffU - uleft; 1154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (uright > urest) || 1156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (carry && (((uright + 1) > urest) || (uright > (urest - 1)))); 1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Calculate C flag value for subtractions. 1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::BorrowFrom(int32_t left, int32_t right) { 1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t uleft = static_cast<uint32_t>(left); 1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t uright = static_cast<uint32_t>(right); 1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (uright > uleft); 1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Calculate V flag value for additions and subtractions. 1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::OverflowFrom(int32_t alu_out, int32_t left, int32_t right, 1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool addition) { 1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool overflow; 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (addition) { 1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // operands have the same sign 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) 1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and operands and result have different sign 1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier && 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // operands have different signs 1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) 1182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and first operand and result have different signs 1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier && 1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return overflow; 1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { 1192342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch *x = reinterpret_cast<intptr_t>(pair->x); 1193342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch *y = reinterpret_cast<intptr_t>(pair->y); 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_BIG_ENDIAN 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *x = static_cast<int32_t>(*pair >> 32); 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *y = static_cast<int32_t>(*pair); 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *x = static_cast<int32_t>(*pair); 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *y = static_cast<int32_t>(*pair >> 32); 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1207342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch// Calls into the V8 runtime. 1208342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtypedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, 1209342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg2, intptr_t arg3, 1210342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg4, intptr_t arg5); 1211342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtypedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1, 1212342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg2, intptr_t arg3, 1213342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg4, intptr_t arg5); 1214342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtypedef ObjectTriple (*SimulatorRuntimeTripleCall)(intptr_t arg0, intptr_t arg1, 1215342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg2, intptr_t arg3, 1216342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg4, 1217342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t arg5); 1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// These prototypes handle the four types of FP calls. 1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1); 1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); 1222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef double (*SimulatorRuntimeFPCall)(double darg0); 1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0); 1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// This signature supports direct call in to API function native callback 1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// (refer to InvocationCallback in v8.h). 1227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0); 1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1); 1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// This signature supports direct call to accessor getter callback. 1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1); 1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef void (*SimulatorRuntimeProfilingGetterCall)(intptr_t arg0, 1233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t arg1, void* arg2); 1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Software interrupt instructions are used by the simulator to call into the 1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// C-based V8 runtime. 1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::SoftwareInterrupt(Instruction* instr) { 1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int svc = instr->SvcValue(); 1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (svc) { 1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCallRtRedirected: { 1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if stack is aligned. Error if not aligned is reported below to 1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // include information on the function called. 1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool stack_aligned = 1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 0; 1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Redirection* redirection = Redirection::FromSwiInstruction(instr); 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int kArgCount = 6; 1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int arg0_regnum = 3; 1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t result_buffer = 0; 1250342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch bool uses_result_buffer = 1251342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE || 1252342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR && 1253342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch !ABI_RETURNS_OBJECT_PAIRS_IN_REGS); 1254342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (uses_result_buffer) { 1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result_buffer = get_register(r3); 1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arg0_regnum++; 1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t arg[kArgCount]; 1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < kArgCount; i++) { 1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arg[i] = get_register(arg0_regnum + i); 1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool fp_call = 1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || 1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || 1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || 1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); 1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This is dodgy but it works because the C entry stubs are never moved. 1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See comment in codegen-arm.cc and bug 1242173. 1269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t saved_lr = special_reg_lr_; 1270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t external = 1271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<intptr_t>(redirection->external_function()); 1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (fp_call) { 1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double dval0, dval1; // one or two double parameters 1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ival; // zero or one integer parameters 1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int iresult = 0; // integer return value 1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double dresult = 0; // double return value 1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GetFpArgs(&dval0, &dval1, &ival); 1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeCall generic_target = 1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeCall>(external); 1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (redirection->type()) { 1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_FP_CALL: 1283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_COMPARE_CALL: 1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p with args %f, %f", 128521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static_cast<void*>(FUNCTION_ADDR(generic_target)), 128621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch dval0, dval1); 1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_CALL: 1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p with arg %f", 129021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static_cast<void*>(FUNCTION_ADDR(generic_target)), 129121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch dval0); 1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_INT_CALL: 1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p with args %f, %" V8PRIdPTR, 129521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static_cast<void*>(FUNCTION_ADDR(generic_target)), 129621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch dval0, ival); 1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!stack_aligned) { 1303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier get_register(sp)); 1305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(stack_aligned); 1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (redirection->type()) { 1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_COMPARE_CALL: { 1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeCompareCall target = 1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeCompareCall>(external); 1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier iresult = target(dval0, dval1); 1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r3, iresult); 1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_FP_CALL: { 1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeFPFPCall target = 1319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeFPFPCall>(external); 1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dresult = target(dval0, dval1); 1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetFpResult(dresult); 1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_CALL: { 1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeFPCall target = 1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeFPCall>(external); 1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dresult = target(dval0); 1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetFpResult(dresult); 1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_INT_CALL: { 1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeFPIntCall target = 1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeFPIntCall>(external); 1334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dresult = target(dval0, ival); 1335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetFpResult(dresult); 1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (redirection->type()) { 1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_COMPARE_CALL: 1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Returned %08x\n", iresult); 1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_FP_CALL: 1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_CALL: 1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ExternalReference::BUILTIN_FP_INT_CALL: 1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Returned %f\n", dresult); 1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { 1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See callers of MacroAssembler::CallApiFunctionAndReturn for 1359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // explanation of register usage. 1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p args %08" V8PRIxPTR, 1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<void*>(external), arg[0]); 1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!stack_aligned) { 1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier get_register(sp)); 1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(stack_aligned); 1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeDirectApiCall target = 1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier target(arg[0]); 1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) { 1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See callers of MacroAssembler::CallApiFunctionAndReturn for 1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // explanation of register usage. 1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p args %08" V8PRIxPTR 1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " %08" V8PRIxPTR, 1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<void*>(external), arg[0], arg[1]); 1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!stack_aligned) { 1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier get_register(sp)); 1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(stack_aligned); 1387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeProfilingApiCall target = 1388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); 1389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier target(arg[0], Redirection::ReverseRedirection(arg[1])); 1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) { 1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See callers of MacroAssembler::CallApiFunctionAndReturn for 1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // explanation of register usage. 1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p args %08" V8PRIxPTR 1395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " %08" V8PRIxPTR, 1396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<void*>(external), arg[0], arg[1]); 1397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!stack_aligned) { 1398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier get_register(sp)); 1400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(stack_aligned); 1404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeDirectGetterCall target = 1405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); 1406342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (!ABI_PASSES_HANDLES_IN_REGS) { 1407342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); 1408342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier target(arg[0], arg[1]); 1410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (redirection->type() == 1411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference::PROFILING_GETTER_CALL) { 1412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Call to host function at %p args %08" V8PRIxPTR 1414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier " %08" V8PRIxPTR " %08" V8PRIxPTR, 1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]); 1416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!stack_aligned) { 1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier get_register(sp)); 1419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(stack_aligned); 1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeProfilingGetterCall target = 1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external); 1425342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (!ABI_PASSES_HANDLES_IN_REGS) { 1426342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); 1427342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2])); 1429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // builtin call. 1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SimulatorRuntimeCall target = 1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<SimulatorRuntimeCall>(external); 1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF( 1435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "Call to host function at %p,\n" 1436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR 1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, 143821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1], 143921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch arg[2], arg[3], arg[4], arg[5]); 1440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!stack_aligned) { 1441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier get_register(sp)); 1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(stack_aligned); 1447342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE) { 1448342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch SimulatorRuntimeTripleCall target = 1449342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch reinterpret_cast<SimulatorRuntimeTripleCall>(external); 1450342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ObjectTriple result = 1451342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); 1452342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (::v8::internal::FLAG_trace_sim) { 1453342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR 1454342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch "}\n", 1455342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch reinterpret_cast<intptr_t>(result.x), 1456342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch reinterpret_cast<intptr_t>(result.y), 1457342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch reinterpret_cast<intptr_t>(result.z)); 1458342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1459342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch memcpy(reinterpret_cast<void*>(result_buffer), &result, 1460342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch sizeof(ObjectTriple)); 1461342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_register(r3, result_buffer); 1462342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } else { 1463342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) { 1464342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch SimulatorRuntimePairCall target = 1465342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch reinterpret_cast<SimulatorRuntimePairCall>(external); 1466342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch ObjectPair result = 1467342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); 1468342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t x; 1469342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t y; 1470342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch decodeObjectPair(&result, &x, &y); 1471342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (::v8::internal::FLAG_trace_sim) { 1472342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); 1473342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1474342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_RETURNS_OBJECT_PAIRS_IN_REGS) { 1475342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_register(r3, x); 1476342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_register(r4, y); 1477342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } else { 1478342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch memcpy(reinterpret_cast<void*>(result_buffer), &result, 1479342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch sizeof(ObjectPair)); 1480342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_register(r3, result_buffer); 1481342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1482342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } else { 1483342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); 1484342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch SimulatorRuntimeCall target = 1485342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch reinterpret_cast<SimulatorRuntimeCall>(external); 1486342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch intptr_t result = 1487342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); 1488342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (::v8::internal::FLAG_trace_sim) { 1489342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch PrintF("Returned %08" V8PRIxPTR "\n", result); 1490342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1491342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_register(r3, result); 1492342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1493342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_pc(saved_lr); 1496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kBreakpoint: { 1499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PPCDebugger dbg(this); 1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dbg.Debug(); 1501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // stop uses all codes greater than 1 << 23. 1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (svc >= (1 << 23)) { 1506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t code = svc & kStopCodeMask; 1507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isWatchedStop(code)) { 1508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IncreaseStopCounter(code); 1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Stop if it is enabled, otherwise go on jumping over the stop 1511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and the message address. 1512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isEnabledStop(code)) { 1513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PPCDebugger dbg(this); 1514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dbg.Stop(instr); 1515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_pc(get_pc() + Instruction::kInstrSize + kPointerSize); 1517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This is not a valid svc code. 1520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 1521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Stop helper functions. 1529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::isStopInstruction(Instruction* instr) { 1530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode); 1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::isWatchedStop(uint32_t code) { 1535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(code <= kMaxStopCode); 1536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return code < kNumOfWatchedStops; 1537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::isEnabledStop(uint32_t code) { 1541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(code <= kMaxStopCode); 1542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Unwatched stops are always enabled. 1543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return !isWatchedStop(code) || 1544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !(watched_stops_[code].count & kStopDisabledBit); 1545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::EnableStop(uint32_t code) { 1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(isWatchedStop(code)); 1550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!isEnabledStop(code)) { 1551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier watched_stops_[code].count &= ~kStopDisabledBit; 1552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::DisableStop(uint32_t code) { 1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(isWatchedStop(code)); 1558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isEnabledStop(code)) { 1559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier watched_stops_[code].count |= kStopDisabledBit; 1560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::IncreaseStopCounter(uint32_t code) { 1565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(code <= kMaxStopCode); 1566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(isWatchedStop(code)); 1567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { 1568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF( 1569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "Stop counter for code %i has overflowed.\n" 1570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "Enabling this code and reseting the counter to 0.\n", 1571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code); 1572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier watched_stops_[code].count = 0; 1573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EnableStop(code); 1574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier watched_stops_[code].count++; 1576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Print a stop status. 1581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::PrintStopInfo(uint32_t code) { 1582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(code <= kMaxStopCode); 1583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!isWatchedStop(code)) { 1584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Stop not watched."); 1585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const char* state = isEnabledStop(code) ? "Enabled" : "Disabled"; 1587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t count = watched_stops_[code].count & ~kStopDisabledBit; 1588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Don't print the state of unused breakpoints. 1589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (count != 0) { 1590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (watched_stops_[code].desc) { 1591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code, 1592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier state, count, watched_stops_[code].desc); 1593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state, 1595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier count); 1596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::SetCR0(intptr_t result, bool setSO) { 1603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bf = 0; 1604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result < 0) { 1605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 1606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result > 0) { 1608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 1609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result == 0) { 1611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 1612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (setSO) { 1614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x10000000; 1615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~0xF0000000) | bf; 1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Simulator::ExecuteBranchConditional(Instruction* instr, BCType type) { 1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bo = instr->Bits(25, 21) << 21; 1622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int condition_bit = instr->Bits(20, 16); 1623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int condition_mask = 0x80000000 >> condition_bit; 1624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (bo) { 1625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBNZF: // Decrement CTR; branch if CTR != 0 and condition false 1626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBEZF: // Decrement CTR; branch if CTR == 0 and condition false 1627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 1628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case BF: { // Branch if condition false 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (condition_reg_ & condition_mask) return; 1630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBNZT: // Decrement CTR; branch if CTR != 0 and condition true 1633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBEZT: // Decrement CTR; branch if CTR == 0 and condition true 1634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 1635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case BT: { // Branch if condition true 1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!(condition_reg_ & condition_mask)) return; 1637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBNZ: // Decrement CTR; branch if CTR != 0 1640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBEZ: // Decrement CTR; branch if CTR == 0 1641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_ctr_ -= 1; 1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((special_reg_ctr_ == 0) != (bo == DCBEZ)) return; 1643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case BA: { // Branch always 1645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Invalid encoding 1649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t old_pc = get_pc(); 1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (type) { 1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BC_OFFSET: { 1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = (instr->Bits(15, 2) << 18) >> 16; 1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_pc(old_pc + offset); 1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BC_LINK_REG: 1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_pc(special_reg_lr_); 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BC_CTR_REG: 1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_pc(special_reg_ctr_); 1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0) == 1) { // LK flag set 1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch special_reg_lr_ = old_pc + 4; 1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Handle execution based on instruction types. 1674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::ExecuteExt1(Instruction* instr) { 1675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (instr->Bits(10, 1) << 1) { 1676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MCRF: 1677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Not used by V8. 1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BCLRX: 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExecuteBranchConditional(instr, BC_LINK_REG); 1680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BCCTRX: 1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExecuteBranchConditional(instr, BC_CTR_REG); 1683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CRNOR: 1685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RFI: 1686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CRANDC: 1687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 1688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ISYNC: { 1689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - simulate isync 1690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CRXOR: { 1693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bt = instr->Bits(25, 21); 1694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ba = instr->Bits(20, 16); 1695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bb = instr->Bits(15, 11); 1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1; 1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1; 1698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bt_val = ba_val ^ bb_val; 1699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bt_val = bt_val << (31 - bt); // shift bit to correct destination 1700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ &= ~(0x80000000 >> bt); 1701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ |= bt_val; 1702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CREQV: { 1705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bt = instr->Bits(25, 21); 1706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ba = instr->Bits(20, 16); 1707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bb = instr->Bits(15, 11); 1708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1; 1709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1; 1710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bt_val = 1 - (ba_val ^ bb_val); 1711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bt_val = bt_val << (31 - bt); // shift bit to correct destination 1712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ &= ~(0x80000000 >> bt); 1713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ |= bt_val; 1714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CRNAND: 1717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CRAND: 1718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CRORC: 1719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CROR: 1720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Not used by V8. 1722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::ExecuteExt2_10bit(Instruction* instr) { 1728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool found = true; 1729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int opcode = instr->Bits(10, 1) << 1; 1731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (opcode) { 1732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SRWX: { 1733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t rs_val = get_register(rs); 17371b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t rb_val = get_register(rb) & 0x3f; 17381b268ca467c924004286c97bac133db489cf43d0Ben Murdoch intptr_t result = (rb_val > 31) ? 0 : rs_val >> rb_val; 1739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 1740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 1742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1745958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SRDX: { 1747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 17511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t rb_val = get_register(rb) & 0x7f; 17521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch intptr_t result = (rb_val > 63) ? 0 : rs_val >> rb_val; 1753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 1754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 1756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SRAW: { 1761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rs_val = get_register(rs); 17651b268ca467c924004286c97bac133db489cf43d0Ben Murdoch intptr_t rb_val = get_register(rb) & 0x3f; 17661b268ca467c924004286c97bac133db489cf43d0Ben Murdoch intptr_t result = (rb_val > 31) ? rs_val >> 31 : rs_val >> rb_val; 1767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 1768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 1770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SRAD: { 1775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 17791b268ca467c924004286c97bac133db489cf43d0Ben Murdoch intptr_t rb_val = get_register(rb) & 0x7f; 17801b268ca467c924004286c97bac133db489cf43d0Ben Murdoch intptr_t result = (rb_val > 63) ? rs_val >> 63 : rs_val >> rb_val; 1781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 1782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 1784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SRAWIX: { 1789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = instr->Bits(15, 11); 1792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rs_val = get_register(rs); 1793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t result = rs_val >> sh; 1794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 1795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 1797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXTSW: { 1802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int shift = kBitsPerPointer - 32; 1803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 1806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = (rs_val << shift) >> shift; 1807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val); 1808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(ra_val); 1810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXTSH: { 1815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int shift = kBitsPerPointer - 16; 1816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 1819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = (rs_val << shift) >> shift; 1820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val); 1821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(ra_val); 1823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXTSB: { 1827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int shift = kBitsPerPointer - 8; 1828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 1831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = (rs_val << shift) >> shift; 1832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val); 1833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(ra_val); 1835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFSUX: 1839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFSX: { 1840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 1841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 1844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 1845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t val = ReadW(ra_val + rb_val, instr); 1846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier float* fptr = reinterpret_cast<float*>(&val); 1847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, static_cast<double>(*fptr)); 1848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LFSUX) { 1849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 1850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 1851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFDUX: 1855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFDX: { 1856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 1857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 1860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + rb_val)); 1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, *dptr); 1863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LFDUX) { 1864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 1865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 1866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFSUX: { 1870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFSX: 1871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frs = instr->RSValue(); 1872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 1875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 1876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier float frs_val = static_cast<float>(get_double_from_d_register(frs)); 1877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t* p = reinterpret_cast<int32_t*>(&frs_val); 1878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteW(ra_val + rb_val, *p, instr); 1879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STFSUX) { 1880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 1881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 1882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFDUX: { 1886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFDX: 1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frs = instr->RSValue(); 1888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 1891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frs_val = get_d_register(frs); 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteDW(ra_val + rb_val, frs_val); 1894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STFDUX) { 1895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 1896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 1897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case POPCNTW: { 1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rs = instr->RSValue(); 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t rs_val = get_register(rs); 1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t count = 0; 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int n = 0; 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t bit = 0x80000000; 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (; n < 32; n++) { 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (bit & rs_val) count++; 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bit >>= 1; 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, count); 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case POPCNTD: { 1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rs = instr->RSValue(); 1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t rs_val = get_register(rs); 1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t count = 0; 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int n = 0; 1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t bit = 0x8000000000000000UL; 1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (; n < 64; n++) { 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (bit & rs_val) count++; 1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bit >>= 1; 1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, count); 1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SYNC: { 1931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - simulate sync 1932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ICBI: { 1935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - simulate icbi 1936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 1939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier found = false; 1940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (found) return found; 1945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier found = true; 1947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = instr->Bits(10, 2) << 2; 1948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (opcode) { 1949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SRADIX: { 1950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 1952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); 1953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 1954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t result = rs_val >> sh; 1955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 1956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 1957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 1958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 1962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier found = false; 1963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return found; 1968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Simulator::ExecuteExt2_9bit_part1(Instruction* instr) { 1972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool found = true; 1973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int opcode = instr->Bits(9, 1) << 1; 1975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (opcode) { 1976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case TW: { 1977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // used for call redirection in simulation mode 1978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SoftwareInterrupt(instr); 1979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CMP: { 1982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 1983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 1984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int cr = instr->Bits(25, 23); 1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bf = 0; 1986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int L = instr->Bit(21); 1988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (L) { 1989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 1991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 1992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < rb_val) { 1993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 1994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > rb_val) { 1996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 1997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == rb_val) { 1999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ra_val = get_register(ra); 2004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rb_val = get_register(rb); 2005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < rb_val) { 2006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 2007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > rb_val) { 2009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 2010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == rb_val) { 2012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition_mask = 0xF0000000U >> (cr * 4); 2017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition = bf >> (cr * 4); 2018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~condition_mask) | condition; 2019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SUBFCX: { 2022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // int oe = instr->Bit(10); 2026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t ra_val = get_register(ra); 2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rb_val = get_register(rb); 2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t alu_out = ~ra_val + rb_val + 1; 20291b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Set carry 20301b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (ra_val <= rb_val) { 2031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000; 20321b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } else { 20331b268ca467c924004286c97bac133db489cf43d0Ben Murdoch special_reg_xer_ &= ~0xF0000000; 2034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 20351b268ca467c924004286c97bac133db489cf43d0Ben Murdoch set_register(rt, alu_out); 2036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 20421b268ca467c924004286c97bac133db489cf43d0Ben Murdoch case SUBFEX: { 20431b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int rt = instr->RTValue(); 20441b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int ra = instr->RAValue(); 20451b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int rb = instr->RBValue(); 20461b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // int oe = instr->Bit(10); 20471b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t ra_val = get_register(ra); 20481b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t rb_val = get_register(rb); 20491b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t alu_out = ~ra_val + rb_val; 20501b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (special_reg_xer_ & 0x20000000) { 20511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch alu_out += 1; 20521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 20531b268ca467c924004286c97bac133db489cf43d0Ben Murdoch set_register(rt, alu_out); 20541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (instr->Bit(0)) { // RC bit set 20551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch SetCR0(static_cast<intptr_t>(alu_out)); 20561b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 20571b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // todo - handle OE bit 20581b268ca467c924004286c97bac133db489cf43d0Ben Murdoch break; 20591b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 2060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ADDCX: { 2061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // int oe = instr->Bit(10); 2065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t ra_val = get_register(ra); 2066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rb_val = get_register(rb); 2067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t alu_out = ra_val + rb_val; 20681b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Set carry 2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (~ra_val < rb_val) { 2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000; 2071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ &= ~0xF0000000; 2073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(static_cast<intptr_t>(alu_out)); 2077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 20811b268ca467c924004286c97bac133db489cf43d0Ben Murdoch case ADDEX: { 20821b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int rt = instr->RTValue(); 20831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int ra = instr->RAValue(); 20841b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int rb = instr->RBValue(); 20851b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // int oe = instr->Bit(10); 20861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t ra_val = get_register(ra); 20871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t rb_val = get_register(rb); 20881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t alu_out = ra_val + rb_val; 20891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (special_reg_xer_ & 0x20000000) { 20901b268ca467c924004286c97bac133db489cf43d0Ben Murdoch alu_out += 1; 20911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 20921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch set_register(rt, alu_out); 20931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (instr->Bit(0)) { // RC bit set 20941b268ca467c924004286c97bac133db489cf43d0Ben Murdoch SetCR0(static_cast<intptr_t>(alu_out)); 20951b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 20961b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // todo - handle OE bit 20971b268ca467c924004286c97bac133db489cf43d0Ben Murdoch break; 20981b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 2099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MULHWX: { 2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ra_val = (get_register(ra) & 0xFFFFFFFF); 2104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rb_val = (get_register(rb) & 0xFFFFFFFF); 2105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t alu_out = (int64_t)ra_val * (int64_t)rb_val; 2106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier alu_out >>= 32; 2107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(static_cast<intptr_t>(alu_out)); 2110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MULHWUX: { 2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t ra_val = (get_register(ra) & 0xFFFFFFFF); 2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t rb_val = (get_register(rb) & 0xFFFFFFFF); 2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t alu_out = (uint64_t)ra_val * (uint64_t)rb_val; 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch alu_out >>= 32; 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, alu_out); 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetCR0(static_cast<intptr_t>(alu_out)); 2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case NEGX: { 2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 2131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = 1 + ~ra_val; 2132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t one = 1; // work-around gcc 2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t kOverflowVal = (one << 63); 2135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 2136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t kOverflowVal = kMinInt; 2137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(10)) { // OE bit set 2140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == kOverflowVal) { 2141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ |= 0xC0000000; // set SO,OV 2142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ &= ~0x40000000; // clear OV 2144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool setSO = (special_reg_xer_ & 0x80000000); 2148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out, setSO); 2149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SLWX: { 2153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t rs_val = get_register(rs); 21571b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t rb_val = get_register(rb) & 0x3f; 21581b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uint32_t result = (rb_val > 31) ? 0 : rs_val << rb_val; 2159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 2160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 2162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SLDX: { 2167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 21711b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t rb_val = get_register(rb) & 0x7f; 21721b268ca467c924004286c97bac133db489cf43d0Ben Murdoch uintptr_t result = (rb_val > 63) ? 0 : rs_val << rb_val; 2173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 2174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 2176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MFVSRD: { 2180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!instr->Bit(0)); 2181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frt_val = get_d_register(frt); 2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, frt_val); 2185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MFVSRWZ: { 2188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!instr->Bit(0)); 2189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frt_val = get_d_register(frt); 2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, static_cast<uint32_t>(frt_val)); 2193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MTVSRD: { 2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!instr->Bit(0)); 2197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t ra_val = get_register(ra); 2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, ra_val); 2201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MTVSRWA: { 2204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!instr->Bit(0)); 2205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t ra_val = static_cast<int32_t>(get_register(ra)); 2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, ra_val); 2209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MTVSRWZ: { 2212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!instr->Bit(0)); 2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint64_t ra_val = static_cast<uint32_t>(get_register(ra)); 2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, ra_val); 2217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 2221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier found = false; 2222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return found; 2227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Simulator::ExecuteExt2_9bit_part2(Instruction* instr) { 2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool found = true; 2232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int opcode = instr->Bits(9, 1) << 1; 2233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (opcode) { 2234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CNTLZWX: { 2235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 2238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t count = 0; 2239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int n = 0; 2240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t bit = 0x80000000; 2241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; n < 32; n++) { 2242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (bit & rs_val) break; 2243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier count++; 2244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 2245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, count); 2247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC Bit set 2248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bf = 0; 2249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (count > 0) { 2250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 2251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (count == 0) { 2253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~0xF0000000) | bf; 2256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CNTLZDX: { 2261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 2264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t count = 0; 2265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int n = 0; 2266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t bit = 0x8000000000000000UL; 2267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; n < 64; n++) { 2268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (bit & rs_val) break; 2269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier count++; 2270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 2271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, count); 2273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC Bit set 2274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bf = 0; 2275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (count > 0) { 2276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 2277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (count == 0) { 2279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~0xF0000000) | bf; 2282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ANDX: { 2287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 2291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val & rb_val; 2293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 2294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC Bit set 2295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ANDCX: { 2300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 2304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val & ~rb_val; 2306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 2307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC Bit set 2308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CMPL: { 2313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int cr = instr->Bits(25, 23); 2316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bf = 0; 2317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int L = instr->Bit(21); 2319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (L) { 2320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t ra_val = get_register(ra); 2322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rb_val = get_register(rb); 2323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < rb_val) { 2324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 2325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > rb_val) { 2327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 2328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == rb_val) { 2330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t ra_val = get_register(ra); 2335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t rb_val = get_register(rb); 2336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < rb_val) { 2337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 2338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > rb_val) { 2340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 2341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == rb_val) { 2343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition_mask = 0xF0000000U >> (cr * 4); 2348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition = bf >> (cr * 4); 2349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~condition_mask) | condition; 2350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SUBFX: { 2353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // int oe = instr->Bit(10); 2357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 2358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rb_val - ra_val; 2360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - figure out underflow 2361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC Bit set 2363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ADDZEX: { 2369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 2372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (special_reg_xer_ & 0x20000000) { 2373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ra_val += 1; 2374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, ra_val); 2376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(ra_val); 2378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case NORX: { 2383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 2387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = ~(rs_val | rb_val); 2389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 2390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MULLW: { 2396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ra_val = (get_register(ra) & 0xFFFFFFFF); 2400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rb_val = (get_register(rb) & 0xFFFFFFFF); 2401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t alu_out = ra_val * rb_val; 2402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MULLD: { 2411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t ra_val = get_register(ra); 2415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t rb_val = get_register(rb); 2416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t alu_out = ra_val * rb_val; 2417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DIVW: { 2426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ra_val = get_register(ra); 2430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rb_val = get_register(rb); 2431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool overflow = (ra_val == kMinInt && rb_val == -1); 2432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // result is undefined if divisor is zero or if operation 2433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // is 0x80000000 / -1. 2434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t alu_out = (rb_val == 0 || overflow) ? -1 : ra_val / rb_val; 2435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(10)) { // OE bit set 2437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (overflow) { 2438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ |= 0xC0000000; // set SO,OV 2439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ &= ~0x40000000; // clear OV 2441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool setSO = (special_reg_xer_ & 0x80000000); 2445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out, setSO); 2446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case DIVWU: { 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t ra_val = get_register(ra); 2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t rb_val = get_register(rb); 2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool overflow = (rb_val == 0); 2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // result is undefined if divisor is zero 2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t alu_out = (overflow) ? -1 : ra_val / rb_val; 2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, alu_out); 2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(10)) { // OE bit set 2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (overflow) { 2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch special_reg_xer_ |= 0xC0000000; // set SO,OV 2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch special_reg_xer_ &= ~0x40000000; // clear OV 2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool setSO = (special_reg_xer_ & 0x80000000); 2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetCR0(alu_out, setSO); 2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DIVD: { 2474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t ra_val = get_register(ra); 2478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t rb_val = get_register(rb); 2479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t one = 1; // work-around gcc 2480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t kMinLongLong = (one << 63); 2481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // result is undefined if divisor is zero or if operation 2482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // is 0x80000000_00000000 / -1. 2483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t alu_out = 2484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1)) 2485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? -1 2486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : ra_val / rb_val; 2487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case DIVDU: { 2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t ra_val = get_register(ra); 2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t rb_val = get_register(rb); 2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // result is undefined if divisor is zero 2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t alu_out = (rb_val == 0) ? -1 : ra_val / rb_val; 2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, alu_out); 2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetCR0(alu_out); 2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // todo - handle OE bit 2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ADDX: { 2511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // int oe = instr->Bit(10); 2515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 2516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = ra_val + rb_val; 2518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 2519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle OE bit 2523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case XORX: { 2526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 2530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val ^ rb_val; 2532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 2533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ORX: { 2539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 2543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val | rb_val; 2545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 2546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 2548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ORC: { 2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rs = instr->RSValue(); 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t rs_val = get_register(rs); 2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t rb_val = get_register(rb); 2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t alu_out = rs_val | ~rb_val; 2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, alu_out); 2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetCR0(alu_out); 2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MFSPR: { 2565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int spr = instr->Bits(20, 11); 2567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (spr != 256) { 2568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Only LRLR supported 2569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, special_reg_lr_); 2571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MTSPR: { 2574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rt_val = get_register(rt); 2576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int spr = instr->Bits(20, 11); 2577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (spr == 256) { 2578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_lr_ = rt_val; 2579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (spr == 288) { 2580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_ctr_ = rt_val; 2581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (spr == 32) { 2582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ = rt_val; 2583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Only LR supported 2585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MFCR: { 2589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, condition_reg_); 2591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STWUX: 2594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STWX: { 2595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rs_val = get_register(rs); 2600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteW(ra_val + rb_val, rs_val, instr); 2602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STWUX) { 2603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 2604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STBUX: 2609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STBX: { 2610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int8_t rs_val = get_register(rs); 2615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteB(ra_val + rb_val, rs_val); 2617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STBUX) { 2618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 2619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STHUX: 2624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STHX: { 2625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t rs_val = get_register(rs); 2630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteH(ra_val + rb_val, rs_val, instr); 2632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STHUX) { 2633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 2634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LWZX: 2639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LWZUX: { 2640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, ReadWU(ra_val + rb_val, instr)); 2646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LWZUX) { 2647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0 && ra != rt); 2648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LWAX: { 2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t rb_val = get_register(rb); 2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, ReadW(ra_val + rb_val, instr)); 2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LDX: 2663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LDUX: { 2664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* result = ReadDW(ra_val + rb_val); 2670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, *result); 2671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LDUX) { 2672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0 && ra != rt); 2673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STDX: 2678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STDUX: { 2679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 2680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 2684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteDW(ra_val + rb_val, rs_val); 2686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STDUX) { 2687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 2688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 2693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LBZX: 2694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LBZUX: { 2695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, ReadBU(ra_val + rb_val) & 0xFF); 2701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LBZUX) { 2702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0 && ra != rt); 2703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LHZX: 2708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LHZUX: { 2709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 2710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 2711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 2712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rb_val = get_register(rb); 2714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, ReadHU(ra_val + rb_val, instr) & 0xFFFF); 2715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LHZUX) { 2716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0 && ra != rt); 2717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + rb_val); 2718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LHAX: 2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LHAUX: { 2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t rb_val = get_register(rb); 2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, ReadH(ra_val + rb_val, instr)); 2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (opcode == LHAUX) { 2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(ra != 0 && ra != rt); 2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, ra_val + rb_val); 2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case DCBF: { 2736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - simulate dcbf 2737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch found = false; 2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return found; 2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Simulator::ExecuteExt2_5bit(Instruction* instr) { 2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int opcode = instr->Bits(5, 1) << 1; 2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (opcode) { 2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ISEL: { 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rb = instr->RBValue(); 2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int condition_bit = instr->RCValue(); 2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int condition_mask = 0x80000000 >> condition_bit; 2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t ra_val = (ra == 0) ? 0 : get_register(ra); 2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t rb_val = get_register(rb); 2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val; 2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, value); 2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: { 2765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Unimplemented: %08x\n", instr->InstructionBits()); 2766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Not used by V8. 2767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::ExecuteExt2(Instruction* instr) { 2773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check first the 10-1 bit versions 2774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ExecuteExt2_10bit(instr)) return; 2775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Now look at the lesser encodings 2776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ExecuteExt2_9bit_part1(instr)) return; 2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ExecuteExt2_9bit_part2(instr)) return; 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExecuteExt2_5bit(instr); 2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Simulator::ExecuteExt3(Instruction* instr) { 2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int opcode = instr->Bits(10, 1) << 1; 2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (opcode) { 2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCFID: { 2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // fcfids 2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frb_val = get_d_register(frb); 2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = static_cast<float>(frb_val); 2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCFIDU: { 2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // fcfidus 2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t frb_val = get_d_register(frb); 2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = static_cast<float>(frb_val); 2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); // Not used by V8. 2805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::ExecuteExt4(Instruction* instr) { 2809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (instr->Bits(5, 1) << 1) { 2810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FDIV: { 2811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = fra_val / frb_val; 2817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FSUB: { 2821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = fra_val - frb_val; 2827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FADD: { 2831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = fra_val + frb_val; 2837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FSQRT: { 2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lazily_initialize_fast_sqrt(isolate_); 2842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = fast_sqrt(frb_val, isolate_); 2846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FSEL: { 2850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frc = instr->RCValue(); 2854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frc_val = get_double_from_d_register(frc); 2857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = ((fra_val >= 0.0) ? frc_val : frb_val); 2858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FMUL: { 2862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frc = instr->RCValue(); 2865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frc_val = get_double_from_d_register(frc); 2867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = fra_val * frc_val; 2868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FMSUB: { 2872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frc = instr->RCValue(); 2876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frc_val = get_double_from_d_register(frc); 2879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = (fra_val * frc_val) - frb_val; 2880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FMADD: { 2884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frc = instr->RCValue(); 2888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frc_val = get_double_from_d_register(frc); 2891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = (fra_val * frc_val) + frb_val; 2892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int opcode = instr->Bits(10, 1) << 1; 2897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (opcode) { 2898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FCMPU: { 2899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fra = instr->RAValue(); 2900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double fra_val = get_double_from_d_register(fra); 2902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int cr = instr->Bits(25, 23); 2904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bf = 0; 2905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (fra_val < frb_val) { 2906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 2907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (fra_val > frb_val) { 2909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 2910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (fra_val == frb_val) { 2912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 2913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (std::isunordered(fra_val, frb_val)) { 2915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x10000000; 2916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int condition_mask = 0xF0000000 >> (cr * 4); 2918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int condition = bf >> (cr * 4); 2919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~condition_mask) | condition; 2920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FRIN: { 2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frb_val = get_double_from_d_register(frb); 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = std::round(frb_val); 2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // UNIMPLEMENTED(); 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FRIZ: { 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frb_val = get_double_from_d_register(frb); 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = std::trunc(frb_val); 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // UNIMPLEMENTED(); 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FRIP: { 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frb_val = get_double_from_d_register(frb); 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = std::ceil(frb_val); 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // UNIMPLEMENTED(); 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FRIM: { 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frb_val = get_double_from_d_register(frb); 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = std::floor(frb_val); 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // UNIMPLEMENTED(); 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FRSP: { 2967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // frsp round 8-byte double-precision value to 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // single-precision value 2971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = static_cast<float>(frb_val); 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 2975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // UNIMPLEMENTED(); 2976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FCFID: { 2980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frb_val = get_d_register(frb); 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = static_cast<double>(frb_val); 2984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 2985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCFIDU: { 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frt = instr->RTValue(); 2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int frb = instr->RBValue(); 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t frb_val = get_d_register(frb); 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = static_cast<double>(frb_val); 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register_from_double(frt, frt_val); 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCTID: 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCTIDZ: { 2997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 2998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 2999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int mode = (opcode == FCTIDZ) ? kRoundToZero 3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : (fp_condition_reg_ & kFPRoundingModeMask); 3002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t frt_val; 3003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t one = 1; // work-around gcc 3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t kMinVal = (one << 63); 3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t kMaxVal = kMinVal - 1; 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool invalid_convert = false; 3007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (std::isnan(frb_val)) { 3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMinVal; 3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch invalid_convert = true; 3011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (mode) { 3013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kRoundToZero: 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::trunc(frb_val); 3015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kRoundToPlusInf: 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::ceil(frb_val); 3018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kRoundToMinusInf: 3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::floor(frb_val); 3021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 3023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Not used by V8. 3024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (frb_val < static_cast<double>(kMinVal)) { 3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMinVal; 3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch invalid_convert = true; 3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (frb_val >= static_cast<double>(kMaxVal)) { 3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMaxVal; 3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch invalid_convert = true; 3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = (int64_t)frb_val; 3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, frt_val); 3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (invalid_convert) SetFPSCR(VXCVI); 3038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCTIDU: 3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FCTIDUZ: { 3042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 3044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int mode = (opcode == FCTIDUZ) 3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? kRoundToZero 3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : (fp_condition_reg_ & kFPRoundingModeMask); 3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t frt_val; 3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t kMinVal = 0; 3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t kMaxVal = kMinVal - 1; 3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool invalid_convert = false; 3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (std::isnan(frb_val)) { 3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMinVal; 3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch invalid_convert = true; 3056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (mode) { 3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToZero: 3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::trunc(frb_val); 3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToPlusInf: 3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::ceil(frb_val); 3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToMinusInf: 3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::floor(frb_val); 3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); // Not used by V8. 3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (frb_val < static_cast<double>(kMinVal)) { 3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMinVal; 3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch invalid_convert = true; 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (frb_val >= static_cast<double>(kMaxVal)) { 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMaxVal; 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch invalid_convert = true; 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = (uint64_t)frb_val; 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, frt_val); 3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (invalid_convert) SetFPSCR(VXCVI); 3083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FCTIW: 3086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FCTIWZ: { 3087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3088958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 3089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int mode = (opcode == FCTIWZ) ? kRoundToZero 3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : (fp_condition_reg_ & kFPRoundingModeMask); 3092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t frt_val; 3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t kMinVal = kMinInt; 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t kMaxVal = kMaxInt; 3095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (std::isnan(frb_val)) { 3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMinVal; 3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (mode) { 3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToZero: 3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::trunc(frb_val); 3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToPlusInf: 3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::ceil(frb_val); 3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToMinusInf: 3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = std::floor(frb_val); 3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kRoundToNearest: { 3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double orig = frb_val; 3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val = lround(frb_val); 3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Round to even if exactly halfway. (lround rounds up) 3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (std::fabs(frb_val - orig) == 0.5 && ((int64_t)frb_val % 2)) { 3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frb_val += ((frb_val > 0) ? -1.0 : 1.0); 3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); // Not used by V8. 3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (frb_val < kMinVal) { 3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMinVal; 3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (frb_val > kMaxVal) { 3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = kMaxVal; 3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frt_val = (int64_t)frb_val; 3128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, frt_val); 3131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FNEG: { 3134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 3136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 3137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frt_val = -frb_val; 3138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 3139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FMR: { 3142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frb_val = get_d_register(frb); 3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, frb_val); 3146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MTFSFI: { 3149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bf = instr->Bits(25, 23); 3150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int imm = instr->Bits(15, 12); 3151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int fp_condition_mask = 0xF0000000 >> (bf * 4); 3152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fp_condition_reg_ &= ~fp_condition_mask; 3153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fp_condition_reg_ |= (imm << (28 - (bf * 4))); 3154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ &= 0xF0FFFFFF; 3156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ |= (imm << 23); 3157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MTFSF: { 3161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frb_dval = get_d_register(frb); 3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t frb_ival = static_cast<int32_t>((frb_dval)&0xffffffff); 3164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int l = instr->Bits(25, 25); 3165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (l == 1) { 3166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fp_condition_reg_ = frb_ival; 3167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 3169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 3172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // int w = instr->Bits(16, 16); 3173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // int flm = instr->Bits(24, 17); 3174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case MFFS: { 3178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t lval = static_cast<int64_t>(fp_condition_reg_); 3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, lval); 3181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MCRFS: { 3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bf = instr->Bits(25, 23); 3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bfa = instr->Bits(20, 18); 3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int cr_shift = (7 - bf) * CRWIDTH; 3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int fp_shift = (7 - bfa) * CRWIDTH; 3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int field_val = (fp_condition_reg_ >> fp_shift) & 0xf; 3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch condition_reg_ &= ~(0x0f << cr_shift); 3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch condition_reg_ |= (field_val << cr_shift); 3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear copied exception bits 3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (bfa) { 3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case 5: 3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ClearFPSCR(VXSOFT); 3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ClearFPSCR(VXSQRT); 3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ClearFPSCR(VXCVI); 3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); 3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MTFSB0: { 3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bt = instr->Bits(25, 21); 3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ClearFPSCR(bt); 3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); 3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MTFSB1: { 3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bt = instr->Bits(25, 21); 3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetFPSCR(bt); 3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->Bit(0)) { // RC bit set 3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); 3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FABS: { 3221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frb = instr->RBValue(); 3223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double frb_val = get_double_from_d_register(frb); 3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double frt_val = std::fabs(frb_val); 3225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, frt_val); 3226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Not used by V8. 3230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 3231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 3233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::ExecuteExt5(Instruction* instr) { 3234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (instr->Bits(4, 2) << 2) { 3235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLDICL: { 3236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 3239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); 3240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); 3241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(sh >= 0 && sh <= 63); 3242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(mb >= 0 && mb <= 63); 3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t result = base::bits::RotateLeft64(rs_val, sh); 3244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t mask = 0xffffffffffffffff >> mb; 3245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLDICR: { 3253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 3256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); 3257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int me = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); 3258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(sh >= 0 && sh <= 63); 3259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(me >= 0 && me <= 63); 3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t result = base::bits::RotateLeft64(rs_val, sh); 3261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t mask = 0xffffffffffffffff << (63 - me); 3262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLDIC: { 3270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 3273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); 3274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); 3275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(sh >= 0 && sh <= 63); 3276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(mb >= 0 && mb <= 63); 3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t result = base::bits::RotateLeft64(rs_val, sh); 3278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t mask = (0xffffffffffffffff >> mb) & (0xffffffffffffffff << sh); 3279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLDIMI: { 3287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 3290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 3291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); 3292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); 3293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int me = 63 - sh; 3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t result = base::bits::RotateLeft64(rs_val, sh); 3295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t mask = 0; 3296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mb < me + 1) { 3297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t bit = 0x8000000000000000 >> mb; 3298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; mb <= me; mb++) { 3299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask |= bit; 3300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 3301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mb == me + 1) { 3303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask = 0xffffffffffffffff; 3304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { // mb > me+1 3305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t bit = 0x8000000000000000 >> (me + 1); // needs to be tested 3306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask = 0xffffffffffffffff; 3307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; me < mb; me++) { 3308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask ^= bit; 3309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 3310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ra_val &= ~mask; 3314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result |= ra_val; 3315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (instr->Bits(4, 1) << 1) { 3323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLDCL: { 3324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 3327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rs_val = get_register(rs); 3328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t rb_val = get_register(rb); 3329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = (rb_val & 0x3f); 3330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); 3331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(sh >= 0 && sh <= 63); 3332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(mb >= 0 && mb <= 63); 3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t result = base::bits::RotateLeft64(rs_val, sh); 3334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t mask = 0xffffffffffffffff >> mb; 3335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 3341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); // Not used by V8. 3344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 3345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 3346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::ExecuteGeneric(Instruction* instr) { 3349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int opcode = instr->OpcodeValue() << 26; 3350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (opcode) { 3351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case SUBFIC: { 3352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 3355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t im_val = instr->Bits(15, 0); 3356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier im_val = SIGN_EXT_IMM16(im_val); 3357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = im_val - ra_val; 3358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 3359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle RC bit 3360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CMPLI: { 3363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int cr = instr->Bits(25, 23); 3366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bf = 0; 3367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 3368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int L = instr->Bit(21); 3369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (L) { 3370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 3371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t ra_val = get_register(ra); 3372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < im_val) { 3373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 3374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > im_val) { 3376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 3377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == im_val) { 3379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 3380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 3382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t ra_val = get_register(ra); 3384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < im_val) { 3385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 3386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > im_val) { 3388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 3389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == im_val) { 3391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 3392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 3395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition_mask = 0xF0000000U >> (cr * 4); 3396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition = bf >> (cr * 4); 3397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~condition_mask) | condition; 3398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CMPI: { 3401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t im_val = instr->Bits(15, 0); 3403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier im_val = SIGN_EXT_IMM16(im_val); 3404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int cr = instr->Bits(25, 23); 3405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bf = 0; 3406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 3407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int L = instr->Bit(21); 3408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (L) { 3409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 3410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 3411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < im_val) { 3412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 3413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > im_val) { 3415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 3416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == im_val) { 3418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 3419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 3421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ra_val = get_register(ra); 3423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val < im_val) { 3424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x80000000; 3425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val > im_val) { 3427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x40000000; 3428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra_val == im_val) { 3430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bf |= 0x20000000; 3431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 3434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition_mask = 0xF0000000U >> (cr * 4); 3435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t condition = bf >> (cr * 4); 3436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_reg_ = (condition_reg_ & ~condition_mask) | condition; 3437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ADDIC: { 3440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t ra_val = get_register(ra); 3443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t alu_out = ra_val + im_val; 3445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check overflow 3446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (~ra_val < im_val) { 3447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000; 3448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_xer_ &= ~0xF0000000; 3450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 3452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ADDI: { 3455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out; 3459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra == 0) { 3460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier alu_out = im_val; 3461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 3463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier alu_out = ra_val + im_val; 3464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 3466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - handle RC bit 3467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ADDIS: { 3470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t im_val = (instr->Bits(15, 0) << 16); 3473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out; 3474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ra == 0) { // treat r0 as zero 3475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier alu_out = im_val; 3476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = get_register(ra); 3478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier alu_out = ra_val + im_val; 3479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, alu_out); 3481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case BCX: { 3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExecuteBranchConditional(instr, BC_OFFSET); 3485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case BX: { 3488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = (instr->Bits(25, 2) << 8) >> 6; 3489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0) == 1) { // LK flag set 3490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_lr_ = get_pc() + 4; 3491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_pc(get_pc() + offset); 3493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - AA flag 3494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXT1: { 3497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteExt1(instr); 3498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLWIMIX: { 3501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t rs_val = get_register(rs); 3504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ra_val = get_register(ra); 3505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = instr->Bits(15, 11); 3506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mb = instr->Bits(10, 6); 3507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int me = instr->Bits(5, 1); 3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t result = base::bits::RotateLeft32(rs_val, sh); 3509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mask = 0; 3510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mb < me + 1) { 3511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit = 0x80000000 >> mb; 3512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; mb <= me; mb++) { 3513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask |= bit; 3514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 3515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mb == me + 1) { 3517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask = 0xffffffff; 3518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { // mb > me+1 3519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit = 0x80000000 >> (me + 1); // needs to be tested 3520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask = 0xffffffff; 3521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; me < mb; me++) { 3522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask ^= bit; 3523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 3524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ra_val &= ~mask; 3528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result |= ra_val; 3529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLWINMX: 3536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case RLWNMX: { 3537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t rs_val = get_register(rs); 3540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int sh = 0; 3541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == RLWINMX) { 3542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sh = instr->Bits(15, 11); 3543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rb = instr->RBValue(); 3545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t rb_val = get_register(rb); 3546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sh = (rb_val & 0x1f); 3547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mb = instr->Bits(10, 6); 3549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int me = instr->Bits(5, 1); 3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t result = base::bits::RotateLeft32(rs_val, sh); 3551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mask = 0; 3552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mb < me + 1) { 3553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit = 0x80000000 >> mb; 3554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; mb <= me; mb++) { 3555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask |= bit; 3556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 3557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mb == me + 1) { 3559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask = 0xffffffff; 3560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { // mb > me+1 3561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit = 0x80000000 >> (me + 1); // needs to be tested 3562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask = 0xffffffff; 3563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; me < mb; me++) { 3564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mask ^= bit; 3565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit >>= 1; 3566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result &= mask; 3569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, result); 3570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0)) { // RC bit set 3571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(result); 3572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ORI: { 3576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 3579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val | im_val; 3581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 3582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ORIS: { 3585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 3588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val | (im_val << 16); 3590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 3591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case XORI: { 3594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 3597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val ^ im_val; 3599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 3600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // todo - set condition based SO bit 3601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case XORIS: { 3604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 3607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val ^ (im_val << 16); 3609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 3610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ANDIx: { 3613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 3616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val & im_val; 3618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 3619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 3620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ANDISx: { 3623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t rs_val = get_register(rs); 3626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t im_val = instr->Bits(15, 0); 3627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t alu_out = rs_val & (im_val << 16); 3628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, alu_out); 3629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SetCR0(alu_out); 3630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXT2: { 3633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteExt2(instr); 3634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LWZU: 3638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LWZ: { 3639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, ReadWU(ra_val + offset, instr)); 3644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LWZU) { 3645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LBZU: 3652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LBZ: { 3653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, ReadB(ra_val + offset) & 0xFF); 3658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LBZU) { 3659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STWU: 3666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STW: { 3667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t rs_val = get_register(rs); 3671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteW(ra_val + offset, rs_val, instr); 3673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STWU) { 3674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // printf("r%d %08x -> %08x\n", rs, rs_val, offset); // 0xdead 3678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STBU: 3682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STB: { 3683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int8_t rs_val = get_register(rs); 3687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteB(ra_val + offset, rs_val); 3689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STBU) { 3690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LHZU: 3697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LHZ: { 3698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff; 3703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, result); 3704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LHZU) { 3705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LHA: 3711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LHAU: { 3712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = instr->RAValue(); 3713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rt = instr->RTValue(); 3714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t result = ReadH(ra_val + offset, instr); 3717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(rt, result); 3718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (opcode == LHAU) { 3719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_register(ra, ra_val + offset); 3720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STHU: 3725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STH: { 3726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int16_t rs_val = get_register(rs); 3730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteH(ra_val + offset, rs_val, instr); 3732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STHU) { 3733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LMW: 3740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STMW: { 3741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 3742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3745958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFSU: 3746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFS: { 3747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t val = ReadW(ra_val + offset, instr); 3752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier float* fptr = reinterpret_cast<float*>(&val); 3753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(frt, static_cast<double>(*fptr)); 3754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LFSU) { 3755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFDU: 3762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LFD: { 3763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frt = instr->RTValue(); 3764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + offset)); 3768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_d_register(frt, *dptr); 3769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == LFDU) { 3770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFSU: { 3777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFS: 3778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frs = instr->RSValue(); 3779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier float frs_val = static_cast<float>(get_double_from_d_register(frs)); 3783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t* p = reinterpret_cast<int32_t*>(&frs_val); 3784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteW(ra_val + offset, *p, instr); 3785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STFSU) { 3786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFDU: 3793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STFD: { 3794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int frs = instr->RSValue(); 3795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); 3797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ra_val = ra == 0 ? 0 : get_register(ra); 3798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t frs_val = get_d_register(frs); 3799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteDW(ra_val + offset, frs_val); 3800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == STFDU) { 3801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case EXT3: { 3808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExecuteExt3(instr); 3809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 3810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXT4: { 3812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteExt4(instr); 3813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 3817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case EXT5: { 3818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteExt5(instr); 3819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case LD: { 3822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rt = instr->RTValue(); 3824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t ra_val = ra == 0 ? 0 : get_register(ra); 3825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); 3826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (instr->Bits(1, 0)) { 3827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case 0: { // ld 3828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* result = ReadDW(ra_val + offset); 3829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, *result); 3830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case 1: { // ldu 3833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* result = ReadDW(ra_val + offset); 3834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, *result); 3835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case 2: { // lwa 3840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t result = ReadW(ra_val + offset, instr); 3841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(rt, result); 3842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case STD: { 3849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int ra = instr->RAValue(); 3850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int rs = instr->RSValue(); 3851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t ra_val = ra == 0 ? 0 : get_register(ra); 3852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t rs_val = get_register(rs); 3853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); 3854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteDW(ra_val + offset, rs_val); 3855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Bit(0) == 1) { // This is the STDU form 3856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(ra != 0); 3857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(ra, ra_val + offset); 3858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 3862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { 3864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 3865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 3866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // NOLINT 3869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::Trace(Instruction* instr) { 3872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::NameConverter converter; 3873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier disasm::Disassembler dasm(converter); 3874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // use a reasonably large buffer 3875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::internal::EmbeddedVector<char, 256> buffer; 3876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); 3877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("%05d %08" V8PRIxPTR " %s\n", icount_, 3878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<intptr_t>(instr), buffer.start()); 3879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 3880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Executes the current instruction. 3883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::ExecuteInstruction(Instruction* instr) { 3884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (v8::internal::FLAG_check_icache) { 3885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CheckICache(isolate_->simulator_i_cache(), instr); 3886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pc_modified_ = false; 3888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_trace_sim) { 3889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Trace(instr); 3890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int opcode = instr->OpcodeValue() << 26; 3892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (opcode == TWI) { 3893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SoftwareInterrupt(instr); 3894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteGeneric(instr); 3896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!pc_modified_) { 3898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_pc(reinterpret_cast<intptr_t>(instr) + Instruction::kInstrSize); 3899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 3901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::Execute() { 3904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get the PC to simulate. Cannot use the accessor here as we need the 3905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // raw PC value and not the one used as input to arithmetic instructions. 3906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t program_counter = get_pc(); 3907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (::v8::internal::FLAG_stop_sim_at == 0) { 3909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Fast version of the dispatch loop without checking whether the simulator 3910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // should be stopping at a particular executed instruction. 3911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (program_counter != end_sim_pc) { 3912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 3913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier icount_++; 3914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteInstruction(instr); 3915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier program_counter = get_pc(); 3916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 3919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // we reach the particular instuction count. 3920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (program_counter != end_sim_pc) { 3921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 3922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier icount_++; 3923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (icount_ == ::v8::internal::FLAG_stop_sim_at) { 3924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PPCDebugger dbg(this); 3925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier dbg.Debug(); 3926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 3927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExecuteInstruction(instr); 3928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier program_counter = get_pc(); 3930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 3933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::CallInternal(byte* entry) { 3936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Adjust JS-based stack limit to C-based stack limit. 3937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate_->stack_guard()->AdjustStackLimitForSimulator(); 3938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3939342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Prepare to execute the code at entry 3940342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_USES_FUNCTION_DESCRIPTORS) { 3941342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // entry is the function descriptor 3942342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_pc(*(reinterpret_cast<intptr_t*>(entry))); 3943342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } else { 3944342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // entry is the instruction address 3945342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_pc(reinterpret_cast<intptr_t>(entry)); 3946342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 3947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3948342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_CALL_VIA_IP) { 3949342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Put target address in ip (for JS prologue). 3950342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch set_register(r12, get_pc()); 3951342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 3952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Put down marker for end of simulation. The simulator will stop simulation 3954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // when the PC reaches this value. By saving the "end simulation" value into 3955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the LR the simulation stops when returning to this call point. 3956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier special_reg_lr_ = end_sim_pc; 3957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Remember the values of non-volatile registers. 3959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r2_val = get_register(r2); 3960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r13_val = get_register(r13); 3961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r14_val = get_register(r14); 3962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r15_val = get_register(r15); 3963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r16_val = get_register(r16); 3964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r17_val = get_register(r17); 3965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r18_val = get_register(r18); 3966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r19_val = get_register(r19); 3967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r20_val = get_register(r20); 3968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r21_val = get_register(r21); 3969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r22_val = get_register(r22); 3970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r23_val = get_register(r23); 3971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r24_val = get_register(r24); 3972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r25_val = get_register(r25); 3973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r26_val = get_register(r26); 3974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r27_val = get_register(r27); 3975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r28_val = get_register(r28); 3976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r29_val = get_register(r29); 3977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r30_val = get_register(r30); 3978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t r31_val = get_register(fp); 3979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Set up the non-volatile registers with a known value. To be able to check 3981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // that they are preserved properly across JS execution. 3982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t callee_saved_value = icount_; 3983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r2, callee_saved_value); 3984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r13, callee_saved_value); 3985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r14, callee_saved_value); 3986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r15, callee_saved_value); 3987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r16, callee_saved_value); 3988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r17, callee_saved_value); 3989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r18, callee_saved_value); 3990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r19, callee_saved_value); 3991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r20, callee_saved_value); 3992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r21, callee_saved_value); 3993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r22, callee_saved_value); 3994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r23, callee_saved_value); 3995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r24, callee_saved_value); 3996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r25, callee_saved_value); 3997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r26, callee_saved_value); 3998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r27, callee_saved_value); 3999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r28, callee_saved_value); 4000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r29, callee_saved_value); 4001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r30, callee_saved_value); 4002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(fp, callee_saved_value); 4003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Start the simulation 4005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Execute(); 4006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the non-volatile registers have been preserved. 4008342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_TOC_REGISTER != 2) { 4009342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(callee_saved_value, get_register(r2)); 4010342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 4011342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (ABI_TOC_REGISTER != 13) { 4012342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(callee_saved_value, get_register(r13)); 4013342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 4014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r14)); 4015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r15)); 4016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r16)); 4017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r17)); 4018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r18)); 4019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r19)); 4020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r20)); 4021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r21)); 4022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r22)); 4023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r23)); 4024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r24)); 4025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r25)); 4026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r26)); 4027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r27)); 4028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r28)); 4029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r29)); 4030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(r30)); 4031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(callee_saved_value, get_register(fp)); 4032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Restore non-volatile registers with the original value. 4034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r2, r2_val); 4035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r13, r13_val); 4036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r14, r14_val); 4037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r15, r15_val); 4038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r16, r16_val); 4039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r17, r17_val); 4040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r18, r18_val); 4041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r19, r19_val); 4042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r20, r20_val); 4043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r21, r21_val); 4044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r22, r22_val); 4045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r23, r23_val); 4046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r24, r24_val); 4047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r25, r25_val); 4048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r26, r26_val); 4049958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r27, r27_val); 4050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r28, r28_val); 4051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r29, r29_val); 4052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(r30, r30_val); 4053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(fp, r31_val); 4054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierintptr_t Simulator::Call(byte* entry, int argument_count, ...) { 4058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier va_list parameters; 4059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier va_start(parameters, argument_count); 4060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Set up arguments 4061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // First eight arguments passed in registers r3-r10. 4063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int reg_arg_count = (argument_count > 8) ? 8 : argument_count; 4064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int stack_arg_count = argument_count - reg_arg_count; 4065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < reg_arg_count; i++) { 4066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(i + 3, va_arg(parameters, intptr_t)); 4067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 4068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Remaining arguments passed on stack. 4070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t original_stack = get_register(sp); 4071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compute position of stack on entry to generated code. 4072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t entry_stack = 4073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (original_stack - 4074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (kNumRequiredStackFrameSlots + stack_arg_count) * sizeof(intptr_t)); 4075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (base::OS::ActivationFrameAlignment() != 0) { 4076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier entry_stack &= -base::OS::ActivationFrameAlignment(); 4077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 4078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Store remaining arguments on stack, from low to high memory. 4079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // +2 is a hack for the LR slot + old SP on PPC 4080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* stack_argument = 4081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reinterpret_cast<intptr_t*>(entry_stack) + kStackFrameExtraParamSlot; 4082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < stack_arg_count; i++) { 4083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier stack_argument[i] = va_arg(parameters, intptr_t); 4084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 4085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier va_end(parameters); 4086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(sp, entry_stack); 4087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4088958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CallInternal(entry); 4089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Pop stack passed arguments. 4091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_EQ(entry_stack, get_register(sp)); 4092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(sp, original_stack); 4093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t result = get_register(r3); 4095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return result; 4096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Simulator::CallFP(byte* entry, double d0, double d1) { 4100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(1, d0); 4101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_d_register_from_double(2, d1); 4102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CallInternal(entry); 4103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) { 4107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CallFP(entry, d0, d1); 4108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t result = get_register(r3); 4109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return result; 4110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierdouble Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) { 4114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CallFP(entry, d0, d1); 4115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return get_double_from_d_register(1); 4116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernieruintptr_t Simulator::PushAddress(uintptr_t address) { 4120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t new_sp = get_register(sp) - sizeof(uintptr_t); 4121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); 4122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *stack_slot = address; 4123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(sp, new_sp); 4124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return new_sp; 4125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernieruintptr_t Simulator::PopAddress() { 4129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t current_sp = get_register(sp); 4130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 4131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t address = *stack_slot; 4132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_register(sp, current_sp + sizeof(uintptr_t)); 4133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return address; 4134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 4136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 4137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // USE_SIMULATOR 4139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // V8_TARGET_ARCH_PPC 4140