11 #include "src/assembler.h" 12 #include "src/base/bits.h" 13 #include "src/codegen.h" 14 #include "src/disasm.h" 15 #include "src/macro-assembler.h" 16 #include "src/ostreams.h" 17 #include "src/ppc/constants-ppc.h" 18 #include "src/ppc/frame-constants-ppc.h" 19 #include "src/ppc/simulator-ppc.h" 20 #include "src/register-configuration.h" 21 #include "src/runtime/runtime-utils.h" 23 #if defined(USE_SIMULATOR) 30 base::LazyInstance<Simulator::GlobalMonitor>::type Simulator::global_monitor_ =
31 LAZY_INSTANCE_INITIALIZER;
37 #define SScanF sscanf // NOLINT 43 explicit PPCDebugger(Simulator* sim) : sim_(sim) {}
45 void Stop(Instruction* instr);
49 static const Instr kBreakpointInstr = (TWI | 0x1F * B21);
50 static const Instr kNopInstr = (ORI);
54 intptr_t GetRegisterValue(
int regnum);
55 double GetRegisterPairDoubleValue(
int regnum);
56 double GetFPDoubleRegisterValue(
int regnum);
57 bool GetValue(
const char* desc, intptr_t* value);
58 bool GetFPDoubleValue(
const char* desc,
double* value);
61 bool SetBreakpoint(Instruction* break_pc);
62 bool DeleteBreakpoint(Instruction* break_pc);
66 void UndoBreakpoints();
67 void RedoBreakpoints();
70 void PPCDebugger::Stop(Instruction* instr) {
73 uint32_t code = instr->SvcValue() & kStopCodeMask;
75 char* msg = *
reinterpret_cast<char**
>(sim_->get_pc() + kInstrSize);
77 if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
78 sim_->watched_stops_[code].desc = msg;
81 if (code != kMaxStopCode) {
82 PrintF(
"Simulator hit stop %u: %s\n", code, msg);
84 PrintF(
"Simulator hit %s\n", msg);
86 sim_->set_pc(sim_->get_pc() + kInstrSize + kPointerSize);
90 intptr_t PPCDebugger::GetRegisterValue(
int regnum) {
91 return sim_->get_register(regnum);
95 double PPCDebugger::GetRegisterPairDoubleValue(
int regnum) {
96 return sim_->get_double_from_register_pair(regnum);
100 double PPCDebugger::GetFPDoubleRegisterValue(
int regnum) {
101 return sim_->get_double_from_d_register(regnum);
105 bool PPCDebugger::GetValue(
const char* desc, intptr_t* value) {
106 int regnum = Registers::Number(desc);
107 if (regnum != kNoRegister) {
108 *value = GetRegisterValue(regnum);
111 if (strncmp(desc,
"0x", 2) == 0) {
112 return SScanF(desc + 2,
"%" V8PRIxPTR,
113 reinterpret_cast<uintptr_t*>(value)) == 1;
115 return SScanF(desc,
"%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) ==
123 bool PPCDebugger::GetFPDoubleValue(
const char* desc,
double* value) {
124 int regnum = DoubleRegisters::Number(desc);
125 if (regnum != kNoRegister) {
126 *value = sim_->get_double_from_d_register(regnum);
133 bool PPCDebugger::SetBreakpoint(Instruction* break_pc) {
135 if (sim_->break_pc_ !=
nullptr) {
140 sim_->break_pc_ = break_pc;
141 sim_->break_instr_ = break_pc->InstructionBits();
148 bool PPCDebugger::DeleteBreakpoint(Instruction* break_pc) {
149 if (sim_->break_pc_ !=
nullptr) {
150 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
153 sim_->break_pc_ =
nullptr;
154 sim_->break_instr_ = 0;
159 void PPCDebugger::UndoBreakpoints() {
160 if (sim_->break_pc_ !=
nullptr) {
161 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
166 void PPCDebugger::RedoBreakpoints() {
167 if (sim_->break_pc_ !=
nullptr) {
168 sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
173 void PPCDebugger::Debug() {
174 intptr_t last_pc = -1;
177 #define COMMAND_SIZE 63 181 #define XSTR(a) STR(a) 183 char cmd[COMMAND_SIZE + 1];
184 char arg1[ARG_SIZE + 1];
185 char arg2[ARG_SIZE + 1];
186 char* argv[3] = {cmd, arg1, arg2};
189 cmd[COMMAND_SIZE] = 0;
197 bool trace = ::v8::internal::FLAG_trace_sim;
198 ::v8::internal::FLAG_trace_sim =
false;
200 while (!done && !sim_->has_bad_pc()) {
201 if (last_pc != sim_->get_pc()) {
206 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc()));
207 PrintF(
" 0x%08" V8PRIxPTR
" %s\n", sim_->get_pc(), buffer.start());
208 last_pc = sim_->get_pc();
210 char* line = ReadLine(
"sim> ");
211 if (line ==
nullptr) {
214 char* last_input = sim_->last_debugger_input();
215 if (strcmp(line,
"\n") == 0 && last_input !=
nullptr) {
219 sim_->set_last_debugger_input(line);
223 int argc = SScanF(line,
224 "%" XSTR(COMMAND_SIZE)
"s " 225 "%" XSTR(ARG_SIZE)
"s " 226 "%" XSTR(ARG_SIZE)
"s",
228 if ((strcmp(cmd,
"si") == 0) || (strcmp(cmd,
"stepi") == 0)) {
232 if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
233 ->InstructionBits() == 0x7D821008) {
234 sim_->set_pc(sim_->get_pc() + kInstrSize);
236 sim_->ExecuteInstruction(
237 reinterpret_cast<Instruction*>(sim_->get_pc()));
240 if (argc == 2 && last_pc != sim_->get_pc() && GetValue(arg1, &value)) {
241 for (
int i = 1;
i < value;
i++) {
246 dasm.InstructionDecode(buffer,
247 reinterpret_cast<byte*>(sim_->get_pc()));
248 PrintF(
" 0x%08" V8PRIxPTR
" %s\n", sim_->get_pc(),
250 sim_->ExecuteInstruction(
251 reinterpret_cast<Instruction*>(sim_->get_pc()));
254 }
else if ((strcmp(cmd,
"c") == 0) || (strcmp(cmd,
"cont") == 0)) {
256 if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
257 ->InstructionBits() == 0x7D821008) {
258 sim_->set_pc(sim_->get_pc() + kInstrSize);
261 sim_->ExecuteInstruction(
262 reinterpret_cast<Instruction*>(sim_->get_pc()));
266 }
else if ((strcmp(cmd,
"p") == 0) || (strcmp(cmd,
"print") == 0)) {
267 if (argc == 2 || (argc == 3 && strcmp(arg2,
"fp") == 0)) {
270 if (strcmp(arg1,
"all") == 0) {
271 for (
int i = 0;
i < kNumRegisters;
i++) {
272 value = GetRegisterValue(
i);
273 PrintF(
" %3s: %08" V8PRIxPTR,
274 RegisterName(Register::from_code(
i)), value);
275 if ((argc == 3 && strcmp(arg2,
"fp") == 0) &&
i < 8 &&
277 dvalue = GetRegisterPairDoubleValue(
i);
278 PrintF(
" (%f)\n", dvalue);
279 }
else if (
i != 0 && !((
i + 1) & 3)) {
283 PrintF(
" pc: %08" V8PRIxPTR
" lr: %08" V8PRIxPTR
285 "ctr: %08" V8PRIxPTR
" xer: %08x cr: %08x\n",
286 sim_->special_reg_pc_, sim_->special_reg_lr_,
287 sim_->special_reg_ctr_, sim_->special_reg_xer_,
288 sim_->condition_reg_);
289 }
else if (strcmp(arg1,
"alld") == 0) {
290 for (
int i = 0;
i < kNumRegisters;
i++) {
291 value = GetRegisterValue(
i);
292 PrintF(
" %3s: %08" V8PRIxPTR
" %11" V8PRIdPTR,
293 RegisterName(Register::from_code(
i)), value, value);
294 if ((argc == 3 && strcmp(arg2,
"fp") == 0) &&
i < 8 &&
296 dvalue = GetRegisterPairDoubleValue(
i);
297 PrintF(
" (%f)\n", dvalue);
298 }
else if (!((
i + 1) % 2)) {
302 PrintF(
" pc: %08" V8PRIxPTR
" lr: %08" V8PRIxPTR
304 "ctr: %08" V8PRIxPTR
" xer: %08x cr: %08x\n",
305 sim_->special_reg_pc_, sim_->special_reg_lr_,
306 sim_->special_reg_ctr_, sim_->special_reg_xer_,
307 sim_->condition_reg_);
308 }
else if (strcmp(arg1,
"allf") == 0) {
309 for (
int i = 0;
i < DoubleRegister::kNumRegisters;
i++) {
310 dvalue = GetFPDoubleRegisterValue(
i);
311 uint64_t as_words = bit_cast<uint64_t>(dvalue);
312 PrintF(
"%3s: %f 0x%08x %08x\n",
313 RegisterName(DoubleRegister::from_code(
i)), dvalue,
314 static_cast<uint32_t>(as_words >> 32),
315 static_cast<uint32_t>(as_words & 0xFFFFFFFF));
317 }
else if (arg1[0] ==
'r' &&
318 (arg1[1] >=
'0' && arg1[1] <=
'9' &&
319 (arg1[2] ==
'\0' || (arg1[2] >=
'0' && arg1[2] <=
'9' &&
320 arg1[3] ==
'\0')))) {
321 int regnum = strtoul(&arg1[1], 0, 10);
322 if (regnum != kNoRegister) {
323 value = GetRegisterValue(regnum);
324 PrintF(
"%s: 0x%08" V8PRIxPTR
" %" V8PRIdPTR
"\n", arg1, value,
327 PrintF(
"%s unrecognized\n", arg1);
330 if (GetValue(arg1, &value)) {
331 PrintF(
"%s: 0x%08" V8PRIxPTR
" %" V8PRIdPTR
"\n", arg1, value,
333 }
else if (GetFPDoubleValue(arg1, &dvalue)) {
334 uint64_t as_words = bit_cast<uint64_t>(dvalue);
335 PrintF(
"%s: %f 0x%08x %08x\n", arg1, dvalue,
336 static_cast<uint32_t>(as_words >> 32),
337 static_cast<uint32_t>(as_words & 0xFFFFFFFF));
339 PrintF(
"%s unrecognized\n", arg1);
343 PrintF(
"print <register>\n");
345 }
else if ((strcmp(cmd,
"po") == 0) ||
346 (strcmp(cmd,
"printobject") == 0)) {
350 if (GetValue(arg1, &value)) {
351 Object* obj =
reinterpret_cast<Object*
>(value);
352 os << arg1 <<
": \n";
357 os << Brief(obj) <<
"\n";
360 os << arg1 <<
" unrecognized\n";
363 PrintF(
"printobject <value>\n");
365 }
else if (strcmp(cmd,
"setpc") == 0) {
368 if (!GetValue(arg1, &value)) {
369 PrintF(
"%s unrecognized\n", arg1);
373 }
else if (strcmp(cmd,
"stack") == 0 || strcmp(cmd,
"mem") == 0) {
374 intptr_t* cur =
nullptr;
375 intptr_t* end =
nullptr;
378 if (strcmp(cmd,
"stack") == 0) {
379 cur =
reinterpret_cast<intptr_t*
>(sim_->get_register(Simulator::sp));
382 if (!GetValue(arg1, &value)) {
383 PrintF(
"%s unrecognized\n", arg1);
386 cur =
reinterpret_cast<intptr_t*
>(value);
391 if (argc == next_arg) {
394 if (!GetValue(argv[next_arg], &words)) {
401 PrintF(
" 0x%08" V8PRIxPTR
": 0x%08" V8PRIxPTR
" %10" V8PRIdPTR,
402 reinterpret_cast<intptr_t>(cur), *cur, *cur);
403 HeapObject* obj =
reinterpret_cast<HeapObject*
>(*cur);
404 intptr_t value = *cur;
405 Heap* current_heap = sim_->isolate_->heap();
406 if (((value & 1) == 0) || current_heap->Contains(obj)) {
408 if ((value & 1) == 0) {
409 PrintF(
"smi %d", PlatformSmiTagging::SmiToInt(
410 reinterpret_cast<Address>(obj)));
419 }
else if (strcmp(cmd,
"disasm") == 0 || strcmp(cmd,
"di") == 0) {
425 byte* prev =
nullptr;
430 cur =
reinterpret_cast<byte*
>(sim_->get_pc());
431 end = cur + (10 * kInstrSize);
432 }
else if (argc == 2) {
433 int regnum = Registers::Number(arg1);
434 if (regnum != kNoRegister || strncmp(arg1,
"0x", 2) == 0) {
437 if (GetValue(arg1, &value)) {
438 cur =
reinterpret_cast<byte*
>(value);
440 end = cur + (10 * kInstrSize);
445 if (GetValue(arg1, &value)) {
446 cur =
reinterpret_cast<byte*
>(sim_->get_pc());
448 end = cur + (value * kInstrSize);
454 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
455 cur =
reinterpret_cast<byte*
>(value1);
456 end = cur + (value2 * kInstrSize);
462 cur += dasm.InstructionDecode(buffer, cur);
463 PrintF(
" 0x%08" V8PRIxPTR
" %s\n", reinterpret_cast<intptr_t>(prev),
466 }
else if (strcmp(cmd,
"gdb") == 0) {
467 PrintF(
"relinquishing control to gdb\n");
468 v8::base::OS::DebugBreak();
469 PrintF(
"regaining control from gdb\n");
470 }
else if (strcmp(cmd,
"break") == 0) {
473 if (GetValue(arg1, &value)) {
474 if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
475 PrintF(
"setting breakpoint failed\n");
478 PrintF(
"%s unrecognized\n", arg1);
481 PrintF(
"break <address>\n");
483 }
else if (strcmp(cmd,
"del") == 0) {
484 if (!DeleteBreakpoint(
nullptr)) {
485 PrintF(
"deleting breakpoint failed\n");
487 }
else if (strcmp(cmd,
"cr") == 0) {
488 PrintF(
"Condition reg: %08x\n", sim_->condition_reg_);
489 }
else if (strcmp(cmd,
"lr") == 0) {
490 PrintF(
"Link reg: %08" V8PRIxPTR
"\n", sim_->special_reg_lr_);
491 }
else if (strcmp(cmd,
"ctr") == 0) {
492 PrintF(
"Ctr reg: %08" V8PRIxPTR
"\n", sim_->special_reg_ctr_);
493 }
else if (strcmp(cmd,
"xer") == 0) {
494 PrintF(
"XER: %08x\n", sim_->special_reg_xer_);
495 }
else if (strcmp(cmd,
"fpscr") == 0) {
496 PrintF(
"FPSCR: %08x\n", sim_->fp_condition_reg_);
497 }
else if (strcmp(cmd,
"stop") == 0) {
499 intptr_t stop_pc = sim_->get_pc() - (kInstrSize + kPointerSize);
500 Instruction* stop_instr =
reinterpret_cast<Instruction*
>(stop_pc);
501 Instruction* msg_address =
502 reinterpret_cast<Instruction*
>(stop_pc + kInstrSize);
503 if ((argc == 2) && (strcmp(arg1,
"unstop") == 0)) {
505 if (sim_->isStopInstruction(stop_instr)) {
506 stop_instr->SetInstructionBits(kNopInstr);
507 msg_address->SetInstructionBits(kNopInstr);
509 PrintF(
"Not at debugger stop.\n");
511 }
else if (argc == 3) {
513 if (strcmp(arg1,
"info") == 0) {
514 if (strcmp(arg2,
"all") == 0) {
515 PrintF(
"Stop information:\n");
516 for (
uint32_t i = 0;
i < sim_->kNumOfWatchedStops;
i++) {
517 sim_->PrintStopInfo(
i);
519 }
else if (GetValue(arg2, &value)) {
520 sim_->PrintStopInfo(value);
522 PrintF(
"Unrecognized argument.\n");
524 }
else if (strcmp(arg1,
"enable") == 0) {
526 if (strcmp(arg2,
"all") == 0) {
527 for (
uint32_t i = 0;
i < sim_->kNumOfWatchedStops;
i++) {
530 }
else if (GetValue(arg2, &value)) {
531 sim_->EnableStop(value);
533 PrintF(
"Unrecognized argument.\n");
535 }
else if (strcmp(arg1,
"disable") == 0) {
537 if (strcmp(arg2,
"all") == 0) {
538 for (
uint32_t i = 0;
i < sim_->kNumOfWatchedStops;
i++) {
539 sim_->DisableStop(
i);
541 }
else if (GetValue(arg2, &value)) {
542 sim_->DisableStop(value);
544 PrintF(
"Unrecognized argument.\n");
548 PrintF(
"Wrong usage. Use help command for more information.\n");
550 }
else if ((strcmp(cmd,
"t") == 0) || strcmp(cmd,
"trace") == 0) {
551 ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
552 PrintF(
"Trace of executed instructions is %s\n",
553 ::v8::internal::FLAG_trace_sim ?
"on" :
"off");
554 }
else if ((strcmp(cmd,
"h") == 0) || (strcmp(cmd,
"help") == 0)) {
556 PrintF(
" continue execution (alias 'c')\n");
557 PrintF(
"stepi [num instructions]\n");
558 PrintF(
" step one/num instruction(s) (alias 'si')\n");
559 PrintF(
"print <register>\n");
560 PrintF(
" print register content (alias 'p')\n");
561 PrintF(
" use register name 'all' to display all integer registers\n");
563 " use register name 'alld' to display integer registers " 564 "with decimal values\n");
565 PrintF(
" use register name 'rN' to display register number 'N'\n");
566 PrintF(
" add argument 'fp' to print register pair double values\n");
568 " use register name 'allf' to display floating-point " 570 PrintF(
"printobject <register>\n");
571 PrintF(
" print an object from a register (alias 'po')\n");
573 PrintF(
" print condition register\n");
575 PrintF(
" print link register\n");
577 PrintF(
" print ctr register\n");
579 PrintF(
" print XER\n");
581 PrintF(
" print FPSCR\n");
582 PrintF(
"stack [<num words>]\n");
583 PrintF(
" dump stack content, default dump 10 words)\n");
584 PrintF(
"mem <address> [<num words>]\n");
585 PrintF(
" dump memory content, default dump 10 words)\n");
586 PrintF(
"disasm [<instructions>]\n");
587 PrintF(
"disasm [<address/register>]\n");
588 PrintF(
"disasm [[<address/register>] <instructions>]\n");
589 PrintF(
" disassemble code, default is 10 instructions\n");
590 PrintF(
" from pc (alias 'di')\n");
592 PrintF(
" enter gdb\n");
593 PrintF(
"break <address>\n");
594 PrintF(
" set a break point on the address\n");
596 PrintF(
" delete the breakpoint\n");
597 PrintF(
"trace (alias 't')\n");
598 PrintF(
" toogle the tracing of all executed statements\n");
599 PrintF(
"stop feature:\n");
600 PrintF(
" Description:\n");
601 PrintF(
" Stops are debug instructions inserted by\n");
602 PrintF(
" the Assembler::stop() function.\n");
603 PrintF(
" When hitting a stop, the Simulator will\n");
604 PrintF(
" stop and give control to the PPCDebugger.\n");
605 PrintF(
" The first %d stop codes are watched:\n",
606 Simulator::kNumOfWatchedStops);
607 PrintF(
" - They can be enabled / disabled: the Simulator\n");
608 PrintF(
" will / won't stop when hitting them.\n");
609 PrintF(
" - The Simulator keeps track of how many times they \n");
610 PrintF(
" are met. (See the info command.) Going over a\n");
611 PrintF(
" disabled stop still increases its counter. \n");
612 PrintF(
" Commands:\n");
613 PrintF(
" stop info all/<code> : print infos about number <code>\n");
614 PrintF(
" or all stop(s).\n");
615 PrintF(
" stop enable/disable all/<code> : enables / disables\n");
616 PrintF(
" all or number <code> stop(s)\n");
617 PrintF(
" stop unstop\n");
618 PrintF(
" ignore the stop instruction at the current location\n");
619 PrintF(
" from now on\n");
621 PrintF(
"Unknown command: %s\n", cmd);
630 ::v8::internal::FLAG_trace_sim = trace;
639 bool Simulator::ICacheMatch(
void* one,
void* two) {
640 DCHECK_EQ(reinterpret_cast<intptr_t>(one) & CachePage::kPageMask, 0);
641 DCHECK_EQ(reinterpret_cast<intptr_t>(two) & CachePage::kPageMask, 0);
646 static uint32_t ICacheHash(
void* key) {
651 static bool AllOnOnePage(
uintptr_t start,
int size) {
652 intptr_t start_page = (start & ~CachePage::kPageMask);
653 intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
654 return start_page == end_page;
658 void Simulator::set_last_debugger_input(
char* input) {
659 DeleteArray(last_debugger_input_);
660 last_debugger_input_ = input;
663 void Simulator::SetRedirectInstruction(Instruction* instruction) {
664 instruction->SetInstructionBits(rtCallRedirInstr | kCallRtRedirected);
667 void Simulator::FlushICache(base::CustomMatcherHashMap* i_cache,
668 void* start_addr,
size_t size) {
669 intptr_t start =
reinterpret_cast<intptr_t
>(start_addr);
670 int intra_line = (start & CachePage::kLineMask);
673 size = ((size - 1) | CachePage::kLineMask) + 1;
674 int offset = (start & CachePage::kPageMask);
675 while (!AllOnOnePage(start, size - 1)) {
676 int bytes_to_flush = CachePage::kPageSize - offset;
677 FlushOnePage(i_cache, start, bytes_to_flush);
678 start += bytes_to_flush;
679 size -= bytes_to_flush;
680 DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask));
684 FlushOnePage(i_cache, start, size);
688 CachePage* Simulator::GetCachePage(base::CustomMatcherHashMap* i_cache,
690 base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page));
691 if (entry->value ==
nullptr) {
692 CachePage* new_page =
new CachePage();
693 entry->value = new_page;
695 return reinterpret_cast<CachePage*
>(entry->value);
700 void Simulator::FlushOnePage(base::CustomMatcherHashMap* i_cache,
701 intptr_t start,
int size) {
702 DCHECK_LE(size, CachePage::kPageSize);
703 DCHECK(AllOnOnePage(start, size - 1));
704 DCHECK_EQ(start & CachePage::kLineMask, 0);
705 DCHECK_EQ(size & CachePage::kLineMask, 0);
706 void* page =
reinterpret_cast<void*
>(start & (~CachePage::kPageMask));
707 int offset = (start & CachePage::kPageMask);
708 CachePage* cache_page = GetCachePage(i_cache, page);
709 char* valid_bytemap = cache_page->ValidityByte(offset);
710 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
713 void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
714 Instruction* instr) {
715 intptr_t address =
reinterpret_cast<intptr_t
>(instr);
716 void* page =
reinterpret_cast<void*
>(address & (~CachePage::kPageMask));
717 void* line =
reinterpret_cast<void*
>(address & (~CachePage::kLineMask));
718 int offset = (address & CachePage::kPageMask);
719 CachePage* cache_page = GetCachePage(i_cache, page);
720 char* cache_valid_byte = cache_page->ValidityByte(offset);
721 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
722 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
725 CHECK_EQ(0, memcmp(reinterpret_cast<void*>(instr),
726 cache_page->CachedData(offset), kInstrSize));
729 memcpy(cached_line, line, CachePage::kLineLength);
730 *cache_valid_byte = CachePage::LINE_VALID;
735 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
738 #if V8_TARGET_ARCH_PPC64 739 size_t stack_size = FLAG_sim_stack_size * KB;
741 size_t stack_size = MB;
743 stack_size += 2 * stack_protection_size_;
744 stack_ =
reinterpret_cast<char*
>(malloc(stack_size));
745 pc_modified_ =
false;
752 for (
int i = 0;
i < kNumGPRs;
i++) {
756 fp_condition_reg_ = 0;
759 special_reg_ctr_ = 0;
762 for (
int i = 0;
i < kNumFPRs;
i++) {
763 fp_registers_[
i] = 0.0;
770 reinterpret_cast<intptr_t
>(stack_) + stack_size - stack_protection_size_;
772 last_debugger_input_ =
nullptr;
775 Simulator::~Simulator() {
781 Simulator* Simulator::current(Isolate* isolate) {
783 isolate->FindOrAllocatePerThreadDataForThisThread();
784 DCHECK_NOT_NULL(isolate_data);
786 Simulator* sim = isolate_data->simulator();
787 if (sim ==
nullptr) {
789 sim =
new Simulator(isolate);
790 isolate_data->set_simulator(sim);
797 void Simulator::set_register(
int reg, intptr_t value) {
798 DCHECK((reg >= 0) && (reg < kNumGPRs));
799 registers_[reg] = value;
804 intptr_t Simulator::get_register(
int reg)
const {
805 DCHECK((reg >= 0) && (reg < kNumGPRs));
808 if (reg >= kNumGPRs)
return 0;
810 return registers_[reg];
814 double Simulator::get_double_from_register_pair(
int reg) {
815 DCHECK((reg >= 0) && (reg < kNumGPRs) && ((reg % 2) == 0));
818 #if !V8_TARGET_ARCH_PPC64 // doesn't make sense in 64bit mode 821 char buffer[
sizeof(fp_registers_[0])];
822 memcpy(buffer, ®isters_[reg], 2 *
sizeof(registers_[0]));
823 memcpy(&dm_val, buffer, 2 *
sizeof(registers_[0]));
830 void Simulator::set_pc(intptr_t value) {
832 special_reg_pc_ = value;
836 bool Simulator::has_bad_pc()
const {
837 return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc));
842 intptr_t Simulator::get_pc()
const {
return special_reg_pc_; }
849 void Simulator::GetFpArgs(
double* x,
double* y, intptr_t* z) {
850 *x = get_double_from_d_register(1);
851 *y = get_double_from_d_register(2);
852 *z = get_register(3);
857 void Simulator::SetFpResult(
const double& result) {
858 set_d_register_from_double(1, result);
862 void Simulator::TrashCallerSaveRegisters() {
864 #if 0 // A good idea to trash volatile registers, needs to be done 865 registers_[2] = 0x50BAD4U;
866 registers_[3] = 0x50BAD4U;
867 registers_[12] = 0x50BAD4U;
871 #define GENERATE_RW_FUNC(size, type) \ 872 type Simulator::Read##size(uintptr_t addr) { \ 874 Read(addr, &value); \ 877 type Simulator::ReadEx##size(uintptr_t addr) { \ 879 ReadEx(addr, &value); \ 882 void Simulator::Write##size(uintptr_t addr, type value) { \ 883 Write(addr, value); \ 885 int32_t Simulator::WriteEx##size(uintptr_t addr, type value) { \ 886 return WriteEx(addr, value); \ 889 RW_VAR_LIST(GENERATE_RW_FUNC);
890 #undef GENERATE_RW_FUNC 896 if (GetCurrentStackPosition() < c_limit) {
897 return reinterpret_cast<uintptr_t>(get_sp());
902 return reinterpret_cast<uintptr_t>(stack_) + stack_protection_size_;
907 void Simulator::Format(Instruction* instr,
const char* format) {
908 PrintF(
"Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR
": %s\n",
909 reinterpret_cast<intptr_t>(instr), format);
915 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
918 uint32_t urest = 0xFFFFFFFFU - uleft;
920 return (uright > urest) ||
921 (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
926 bool Simulator::BorrowFrom(int32_t left, int32_t right) {
930 return (uright > uleft);
935 bool Simulator::OverflowFrom(int32_t alu_out, int32_t left, int32_t right,
940 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
943 ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
946 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
949 ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
955 #if V8_TARGET_ARCH_PPC64 956 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
957 *x =
reinterpret_cast<intptr_t
>(pair->x);
958 *y =
reinterpret_cast<intptr_t
>(pair->y);
961 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
962 #if V8_TARGET_BIG_ENDIAN 963 *x =
static_cast<int32_t
>(*pair >> 32);
964 *y =
static_cast<int32_t
>(*pair);
966 *x =
static_cast<int32_t
>(*pair);
967 *y =
static_cast<int32_t
>(*pair >> 32);
973 typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
974 intptr_t arg2, intptr_t arg3,
975 intptr_t arg4, intptr_t arg5,
976 intptr_t arg6, intptr_t arg7,
978 typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1,
979 intptr_t arg2, intptr_t arg3,
980 intptr_t arg4, intptr_t arg5);
983 typedef int (*SimulatorRuntimeCompareCall)(
double darg0,
double darg1);
984 typedef double (*SimulatorRuntimeFPFPCall)(
double darg0,
double darg1);
985 typedef double (*SimulatorRuntimeFPCall)(
double darg0);
986 typedef double (*SimulatorRuntimeFPIntCall)(
double darg0, intptr_t arg0);
990 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0);
991 typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0,
void* arg1);
994 typedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1);
995 typedef void (*SimulatorRuntimeProfilingGetterCall)(intptr_t arg0,
996 intptr_t arg1,
void* arg2);
1000 void Simulator::SoftwareInterrupt(Instruction* instr) {
1001 int svc = instr->SvcValue();
1003 case kCallRtRedirected: {
1006 bool stack_aligned =
1007 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) ==
1009 Redirection* redirection = Redirection::FromInstruction(instr);
1010 const int kArgCount = 9;
1011 const int kRegisterArgCount = 8;
1012 int arg0_regnum = 3;
1013 intptr_t result_buffer = 0;
1014 bool uses_result_buffer =
1015 (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR &&
1016 !ABI_RETURNS_OBJECT_PAIRS_IN_REGS);
1017 if (uses_result_buffer) {
1018 result_buffer = get_register(r3);
1021 intptr_t arg[kArgCount];
1023 for (
int i = 0;
i < kRegisterArgCount;
i++) {
1024 arg[
i] = get_register(arg0_regnum +
i);
1026 intptr_t* stack_pointer =
reinterpret_cast<intptr_t*
>(get_register(sp));
1028 arg[kRegisterArgCount] = stack_pointer[kStackFrameExtraParamSlot];
1029 STATIC_ASSERT(kArgCount == kRegisterArgCount + 1);
1030 STATIC_ASSERT(kMaxCParameters == 9);
1032 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1033 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1034 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1035 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1038 intptr_t saved_lr = special_reg_lr_;
1040 reinterpret_cast<intptr_t
>(redirection->external_function());
1042 double dval0, dval1;
1046 GetFpArgs(&dval0, &dval1, &ival);
1047 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1048 SimulatorRuntimeCall generic_target =
1049 reinterpret_cast<SimulatorRuntimeCall
>(external);
1050 switch (redirection->type()) {
1051 case ExternalReference::BUILTIN_FP_FP_CALL:
1052 case ExternalReference::BUILTIN_COMPARE_CALL:
1053 PrintF(
"Call to host function at %p with args %f, %f",
1054 reinterpret_cast<void*>(FUNCTION_ADDR(generic_target)),
1057 case ExternalReference::BUILTIN_FP_CALL:
1058 PrintF(
"Call to host function at %p with arg %f",
1059 reinterpret_cast<void*>(FUNCTION_ADDR(generic_target)),
1062 case ExternalReference::BUILTIN_FP_INT_CALL:
1063 PrintF(
"Call to host function at %p with args %f, %" V8PRIdPTR,
1064 reinterpret_cast<void*>(FUNCTION_ADDR(generic_target)),
1071 if (!stack_aligned) {
1072 PrintF(
" with unaligned stack %08" V8PRIxPTR
"\n",
1077 CHECK(stack_aligned);
1078 switch (redirection->type()) {
1079 case ExternalReference::BUILTIN_COMPARE_CALL: {
1080 SimulatorRuntimeCompareCall target =
1081 reinterpret_cast<SimulatorRuntimeCompareCall
>(external);
1082 iresult = target(dval0, dval1);
1083 set_register(r3, iresult);
1086 case ExternalReference::BUILTIN_FP_FP_CALL: {
1087 SimulatorRuntimeFPFPCall target =
1088 reinterpret_cast<SimulatorRuntimeFPFPCall
>(external);
1089 dresult = target(dval0, dval1);
1090 SetFpResult(dresult);
1093 case ExternalReference::BUILTIN_FP_CALL: {
1094 SimulatorRuntimeFPCall target =
1095 reinterpret_cast<SimulatorRuntimeFPCall
>(external);
1096 dresult = target(dval0);
1097 SetFpResult(dresult);
1100 case ExternalReference::BUILTIN_FP_INT_CALL: {
1101 SimulatorRuntimeFPIntCall target =
1102 reinterpret_cast<SimulatorRuntimeFPIntCall
>(external);
1103 dresult = target(dval0, ival);
1104 SetFpResult(dresult);
1111 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1112 switch (redirection->type()) {
1113 case ExternalReference::BUILTIN_COMPARE_CALL:
1114 PrintF(
"Returned %08x\n", iresult);
1116 case ExternalReference::BUILTIN_FP_FP_CALL:
1117 case ExternalReference::BUILTIN_FP_CALL:
1118 case ExternalReference::BUILTIN_FP_INT_CALL:
1119 PrintF(
"Returned %f\n", dresult);
1126 }
else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1129 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1130 PrintF(
"Call to host function at %p args %08" V8PRIxPTR,
1131 reinterpret_cast<void*>(external), arg[0]);
1132 if (!stack_aligned) {
1133 PrintF(
" with unaligned stack %08" V8PRIxPTR
"\n",
1138 CHECK(stack_aligned);
1139 SimulatorRuntimeDirectApiCall target =
1140 reinterpret_cast<SimulatorRuntimeDirectApiCall
>(external);
1142 }
else if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
1145 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1146 PrintF(
"Call to host function at %p args %08" V8PRIxPTR
1148 reinterpret_cast<void*>(external), arg[0], arg[1]);
1149 if (!stack_aligned) {
1150 PrintF(
" with unaligned stack %08" V8PRIxPTR
"\n",
1155 CHECK(stack_aligned);
1156 SimulatorRuntimeProfilingApiCall target =
1157 reinterpret_cast<SimulatorRuntimeProfilingApiCall
>(external);
1158 target(arg[0], Redirection::ReverseRedirection(arg[1]));
1159 }
else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
1162 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1163 PrintF(
"Call to host function at %p args %08" V8PRIxPTR
1165 reinterpret_cast<void*>(external), arg[0], arg[1]);
1166 if (!stack_aligned) {
1167 PrintF(
" with unaligned stack %08" V8PRIxPTR
"\n",
1172 CHECK(stack_aligned);
1173 SimulatorRuntimeDirectGetterCall target =
1174 reinterpret_cast<SimulatorRuntimeDirectGetterCall
>(external);
1175 if (!ABI_PASSES_HANDLES_IN_REGS) {
1176 arg[0] = *(
reinterpret_cast<intptr_t*
>(arg[0]));
1178 target(arg[0], arg[1]);
1179 }
else if (redirection->type() ==
1180 ExternalReference::PROFILING_GETTER_CALL) {
1181 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1182 PrintF(
"Call to host function at %p args %08" V8PRIxPTR
1183 " %08" V8PRIxPTR
" %08" V8PRIxPTR,
1184 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]);
1185 if (!stack_aligned) {
1186 PrintF(
" with unaligned stack %08" V8PRIxPTR
"\n",
1191 CHECK(stack_aligned);
1192 SimulatorRuntimeProfilingGetterCall target =
1193 reinterpret_cast<SimulatorRuntimeProfilingGetterCall
>(external);
1194 if (!ABI_PASSES_HANDLES_IN_REGS) {
1195 arg[0] = *(
reinterpret_cast<intptr_t*
>(arg[0]));
1197 target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
1200 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1201 SimulatorRuntimeCall target =
1202 reinterpret_cast<SimulatorRuntimeCall
>(external);
1204 "Call to host function at %p,\n" 1205 "\t\t\t\targs %08" V8PRIxPTR
", %08" V8PRIxPTR
", %08" V8PRIxPTR
1206 ", %08" V8PRIxPTR
", %08" V8PRIxPTR
", %08" V8PRIxPTR
1207 ", %08" V8PRIxPTR
", %08" V8PRIxPTR
", %08" V8PRIxPTR,
1208 reinterpret_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1],
1209 arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8]);
1210 if (!stack_aligned) {
1211 PrintF(
" with unaligned stack %08" V8PRIxPTR
"\n",
1216 CHECK(stack_aligned);
1217 if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) {
1218 SimulatorRuntimePairCall target =
1219 reinterpret_cast<SimulatorRuntimePairCall
>(external);
1221 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
1224 decodeObjectPair(&result, &x, &y);
1225 if (::v8::internal::FLAG_trace_sim) {
1226 PrintF(
"Returned {%08" V8PRIxPTR
", %08" V8PRIxPTR
"}\n", x, y);
1228 if (ABI_RETURNS_OBJECT_PAIRS_IN_REGS) {
1229 set_register(r3, x);
1230 set_register(r4, y);
1232 memcpy(reinterpret_cast<void*>(result_buffer), &result,
1233 sizeof(ObjectPair));
1234 set_register(r3, result_buffer);
1237 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL);
1238 SimulatorRuntimeCall target =
1239 reinterpret_cast<SimulatorRuntimeCall
>(external);
1240 intptr_t result = target(arg[0], arg[1], arg[2], arg[3], arg[4],
1241 arg[5], arg[6], arg[7], arg[8]);
1242 if (::v8::internal::FLAG_trace_sim) {
1243 PrintF(
"Returned %08" V8PRIxPTR
"\n", result);
1245 set_register(r3, result);
1252 PPCDebugger dbg(
this);
1258 if (svc >= (1 << 23)) {
1259 uint32_t code = svc & kStopCodeMask;
1260 if (isWatchedStop(code)) {
1261 IncreaseStopCounter(code);
1265 if (isEnabledStop(code)) {
1266 PPCDebugger dbg(
this);
1269 set_pc(get_pc() + kInstrSize + kPointerSize);
1282 bool Simulator::isStopInstruction(Instruction* instr) {
1283 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
1287 bool Simulator::isWatchedStop(
uint32_t code) {
1288 DCHECK_LE(code, kMaxStopCode);
1289 return code < kNumOfWatchedStops;
1293 bool Simulator::isEnabledStop(
uint32_t code) {
1294 DCHECK_LE(code, kMaxStopCode);
1296 return !isWatchedStop(code) ||
1297 !(watched_stops_[code].count & kStopDisabledBit);
1301 void Simulator::EnableStop(
uint32_t code) {
1302 DCHECK(isWatchedStop(code));
1303 if (!isEnabledStop(code)) {
1304 watched_stops_[code].count &= ~kStopDisabledBit;
1309 void Simulator::DisableStop(
uint32_t code) {
1310 DCHECK(isWatchedStop(code));
1311 if (isEnabledStop(code)) {
1312 watched_stops_[code].count |= kStopDisabledBit;
1317 void Simulator::IncreaseStopCounter(
uint32_t code) {
1318 DCHECK_LE(code, kMaxStopCode);
1319 DCHECK(isWatchedStop(code));
1320 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7FFFFFFF) {
1322 "Stop counter for code %i has overflowed.\n" 1323 "Enabling this code and reseting the counter to 0.\n",
1325 watched_stops_[code].count = 0;
1328 watched_stops_[code].count++;
1334 void Simulator::PrintStopInfo(
uint32_t code) {
1335 DCHECK_LE(code, kMaxStopCode);
1336 if (!isWatchedStop(code)) {
1337 PrintF(
"Stop not watched.");
1339 const char* state = isEnabledStop(code) ?
"Enabled" :
"Disabled";
1340 int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
1343 if (watched_stops_[code].desc) {
1344 PrintF(
"stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code,
1345 state, count, watched_stops_[code].desc);
1347 PrintF(
"stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state,
1355 void Simulator::SetCR0(intptr_t result,
bool setSO) {
1369 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
1373 void Simulator::ExecuteBranchConditional(Instruction* instr, BCType type) {
1374 int bo = instr->Bits(25, 21) << 21;
1375 int condition_bit = instr->Bits(20, 16);
1376 int condition_mask = 0x80000000 >> condition_bit;
1382 if (condition_reg_ & condition_mask)
return;
1389 if (!(condition_reg_ & condition_mask))
return;
1394 special_reg_ctr_ -= 1;
1395 if ((special_reg_ctr_ == 0) != (bo == DCBEZ))
return;
1404 intptr_t old_pc = get_pc();
1408 int offset = (instr->Bits(15, 2) << 18) >> 16;
1409 set_pc(old_pc + offset);
1413 set_pc(special_reg_lr_);
1416 set_pc(special_reg_ctr_);
1420 if (instr->Bit(0) == 1) {
1421 special_reg_lr_ = old_pc + 4;
1425 void Simulator::ExecuteGeneric(Instruction* instr) {
1426 uint32_t opcode = instr->OpcodeBase();
1429 int rt = instr->RTValue();
1430 int ra = instr->RAValue();
1431 intptr_t ra_val = get_register(ra);
1432 int32_t im_val = instr->Bits(15, 0);
1433 im_val = SIGN_EXT_IMM16(im_val);
1434 intptr_t alu_out = im_val - ra_val;
1435 set_register(rt, alu_out);
1440 int ra = instr->RAValue();
1441 uint32_t im_val = instr->Bits(15, 0);
1442 int cr = instr->Bits(25, 23);
1444 #if V8_TARGET_ARCH_PPC64 1445 int L = instr->Bit(21);
1449 if (ra_val < im_val) {
1452 if (ra_val > im_val) {
1455 if (ra_val == im_val) {
1458 #if V8_TARGET_ARCH_PPC64 1460 uint32_t ra_val = get_register(ra);
1461 if (ra_val < im_val) {
1464 if (ra_val > im_val) {
1467 if (ra_val == im_val) {
1472 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
1473 uint32_t condition = bf >> (cr * 4);
1474 condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
1478 int ra = instr->RAValue();
1479 int32_t im_val = instr->Bits(15, 0);
1480 im_val = SIGN_EXT_IMM16(im_val);
1481 int cr = instr->Bits(25, 23);
1483 #if V8_TARGET_ARCH_PPC64 1484 int L = instr->Bit(21);
1487 intptr_t ra_val = get_register(ra);
1488 if (ra_val < im_val) {
1491 if (ra_val > im_val) {
1494 if (ra_val == im_val) {
1497 #if V8_TARGET_ARCH_PPC64 1499 int32_t ra_val = get_register(ra);
1500 if (ra_val < im_val) {
1503 if (ra_val > im_val) {
1506 if (ra_val == im_val) {
1511 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
1512 uint32_t condition = bf >> (cr * 4);
1513 condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
1517 int rt = instr->RTValue();
1518 int ra = instr->RAValue();
1520 uintptr_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0));
1523 if (~ra_val < im_val) {
1524 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
1526 special_reg_xer_ &= ~0xF0000000;
1528 set_register(rt, alu_out);
1532 int rt = instr->RTValue();
1533 int ra = instr->RAValue();
1534 int32_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0));
1539 intptr_t ra_val = get_register(ra);
1540 alu_out = ra_val + im_val;
1542 set_register(rt, alu_out);
1547 int rt = instr->RTValue();
1548 int ra = instr->RAValue();
1549 int32_t im_val = (instr->Bits(15, 0) << 16);
1554 intptr_t ra_val = get_register(ra);
1555 alu_out = ra_val + im_val;
1557 set_register(rt, alu_out);
1561 ExecuteBranchConditional(instr, BC_OFFSET);
1565 int offset = (instr->Bits(25, 2) << 8) >> 6;
1566 if (instr->Bit(0) == 1) {
1567 special_reg_lr_ = get_pc() + 4;
1569 set_pc(get_pc() + offset);
1576 ExecuteBranchConditional(instr, BC_LINK_REG);
1579 ExecuteBranchConditional(instr, BC_CTR_REG);
1590 int bt = instr->Bits(25, 21);
1591 int ba = instr->Bits(20, 16);
1592 int bb = instr->Bits(15, 11);
1593 int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
1594 int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
1595 int bt_val = ba_val ^ bb_val;
1596 bt_val = bt_val << (31 - bt);
1597 condition_reg_ &= ~(0x80000000 >> bt);
1598 condition_reg_ |= bt_val;
1602 int bt = instr->Bits(25, 21);
1603 int ba = instr->Bits(20, 16);
1604 int bb = instr->Bits(15, 11);
1605 int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
1606 int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
1607 int bt_val = 1 - (ba_val ^ bb_val);
1608 bt_val = bt_val << (31 - bt);
1609 condition_reg_ &= ~(0x80000000 >> bt);
1610 condition_reg_ |= bt_val;
1621 int ra = instr->RAValue();
1622 int rs = instr->RSValue();
1623 uint32_t rs_val = get_register(rs);
1624 int32_t ra_val = get_register(ra);
1625 int sh = instr->Bits(15, 11);
1626 int mb = instr->Bits(10, 6);
1627 int me = instr->Bits(5, 1);
1628 uint32_t result = base::bits::RotateLeft32(rs_val, sh);
1631 int bit = 0x80000000 >> mb;
1632 for (; mb <= me; mb++) {
1636 }
else if (mb == me + 1) {
1639 int bit = 0x80000000 >> (me + 1);
1641 for (; me < mb; me++) {
1649 set_register(ra, result);
1650 if (instr->Bit(0)) {
1657 int ra = instr->RAValue();
1658 int rs = instr->RSValue();
1659 uint32_t rs_val = get_register(rs);
1661 if (opcode == RLWINMX) {
1662 sh = instr->Bits(15, 11);
1664 int rb = instr->RBValue();
1665 uint32_t rb_val = get_register(rb);
1666 sh = (rb_val & 0x1F);
1668 int mb = instr->Bits(10, 6);
1669 int me = instr->Bits(5, 1);
1670 uint32_t result = base::bits::RotateLeft32(rs_val, sh);
1673 int bit = 0x80000000 >> mb;
1674 for (; mb <= me; mb++) {
1678 }
else if (mb == me + 1) {
1681 int bit = 0x80000000 >> (me + 1);
1683 for (; me < mb; me++) {
1689 set_register(ra, result);
1690 if (instr->Bit(0)) {
1696 int rs = instr->RSValue();
1697 int ra = instr->RAValue();
1698 intptr_t rs_val = get_register(rs);
1699 uint32_t im_val = instr->Bits(15, 0);
1700 intptr_t alu_out = rs_val | im_val;
1701 set_register(ra, alu_out);
1705 int rs = instr->RSValue();
1706 int ra = instr->RAValue();
1707 intptr_t rs_val = get_register(rs);
1708 uint32_t im_val = instr->Bits(15, 0);
1709 intptr_t alu_out = rs_val | (im_val << 16);
1710 set_register(ra, alu_out);
1714 int rs = instr->RSValue();
1715 int ra = instr->RAValue();
1716 intptr_t rs_val = get_register(rs);
1717 uint32_t im_val = instr->Bits(15, 0);
1718 intptr_t alu_out = rs_val ^ im_val;
1719 set_register(ra, alu_out);
1724 int rs = instr->RSValue();
1725 int ra = instr->RAValue();
1726 intptr_t rs_val = get_register(rs);
1727 uint32_t im_val = instr->Bits(15, 0);
1728 intptr_t alu_out = rs_val ^ (im_val << 16);
1729 set_register(ra, alu_out);
1733 int rs = instr->RSValue();
1734 int ra = instr->RAValue();
1735 intptr_t rs_val = get_register(rs);
1736 uint32_t im_val = instr->Bits(15, 0);
1737 intptr_t alu_out = rs_val & im_val;
1738 set_register(ra, alu_out);
1743 int rs = instr->RSValue();
1744 int ra = instr->RAValue();
1745 intptr_t rs_val = get_register(rs);
1746 uint32_t im_val = instr->Bits(15, 0);
1747 intptr_t alu_out = rs_val & (im_val << 16);
1748 set_register(ra, alu_out);
1753 int rs = instr->RSValue();
1754 int ra = instr->RAValue();
1755 int rb = instr->RBValue();
1756 uint32_t rs_val = get_register(rs);
1757 uintptr_t rb_val = get_register(rb) & 0x3F;
1758 intptr_t result = (rb_val > 31) ? 0 : rs_val >> rb_val;
1759 set_register(ra, result);
1760 if (instr->Bit(0)) {
1765 #if V8_TARGET_ARCH_PPC64 1767 int rs = instr->RSValue();
1768 int ra = instr->RAValue();
1769 int rb = instr->RBValue();
1771 uintptr_t rb_val = get_register(rb) & 0x7F;
1772 intptr_t result = (rb_val > 63) ? 0 : rs_val >> rb_val;
1773 set_register(ra, result);
1774 if (instr->Bit(0)) {
1781 int rt = instr->RTValue();
1782 int ra = instr->RAValue();
1783 int rb = instr->RBValue();
1784 uint32_t ra_val = get_register(ra);
1785 uint32_t rb_val = get_register(rb);
1786 uint32_t alu_out = (rb_val == 0) ? -1 : ra_val % rb_val;
1787 set_register(rt, alu_out);
1790 #if V8_TARGET_ARCH_PPC64 1792 int rt = instr->RTValue();
1793 int ra = instr->RAValue();
1794 int rb = instr->RBValue();
1795 uint64_t ra_val = get_register(ra);
1796 uint64_t rb_val = get_register(rb);
1797 uint64_t alu_out = (rb_val == 0) ? -1 : ra_val % rb_val;
1798 set_register(rt, alu_out);
1803 int rt = instr->RTValue();
1804 int ra = instr->RAValue();
1805 int rb = instr->RBValue();
1806 int32_t ra_val = get_register(ra);
1807 int32_t rb_val = get_register(rb);
1808 bool overflow = (ra_val == kMinInt && rb_val == -1);
1811 int32_t alu_out = (rb_val == 0 || overflow) ? -1 : ra_val % rb_val;
1812 set_register(rt, alu_out);
1815 #if V8_TARGET_ARCH_PPC64 1817 int rt = instr->RTValue();
1818 int ra = instr->RAValue();
1819 int rb = instr->RBValue();
1820 int64_t ra_val = get_register(ra);
1821 int64_t rb_val = get_register(rb);
1823 int64_t kMinLongLong = (one << 63);
1827 (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1))
1830 set_register(rt, alu_out);
1835 int rs = instr->RSValue();
1836 int ra = instr->RAValue();
1837 int rb = instr->RBValue();
1838 int32_t rs_val = get_register(rs);
1839 intptr_t rb_val = get_register(rb) & 0x3F;
1840 intptr_t result = (rb_val > 31) ? rs_val >> 31 : rs_val >> rb_val;
1841 set_register(ra, result);
1842 if (instr->Bit(0)) {
1847 #if V8_TARGET_ARCH_PPC64 1849 int rs = instr->RSValue();
1850 int ra = instr->RAValue();
1851 int rb = instr->RBValue();
1852 intptr_t rs_val = get_register(rs);
1853 intptr_t rb_val = get_register(rb) & 0x7F;
1854 intptr_t result = (rb_val > 63) ? rs_val >> 63 : rs_val >> rb_val;
1855 set_register(ra, result);
1856 if (instr->Bit(0)) {
1863 int ra = instr->RAValue();
1864 int rs = instr->RSValue();
1865 int sh = instr->Bits(15, 11);
1866 int32_t rs_val = get_register(rs);
1867 intptr_t result = rs_val >> sh;
1868 set_register(ra, result);
1869 if (instr->Bit(0)) {
1874 #if V8_TARGET_ARCH_PPC64 1876 const int shift = kBitsPerSystemPointer - 32;
1877 int ra = instr->RAValue();
1878 int rs = instr->RSValue();
1879 intptr_t rs_val = get_register(rs);
1880 intptr_t ra_val = (rs_val << shift) >> shift;
1881 set_register(ra, ra_val);
1882 if (instr->Bit(0)) {
1889 const int shift = kBitsPerSystemPointer - 16;
1890 int ra = instr->RAValue();
1891 int rs = instr->RSValue();
1892 intptr_t rs_val = get_register(rs);
1893 intptr_t ra_val = (rs_val << shift) >> shift;
1894 set_register(ra, ra_val);
1895 if (instr->Bit(0)) {
1901 const int shift = kBitsPerSystemPointer - 8;
1902 int ra = instr->RAValue();
1903 int rs = instr->RSValue();
1904 intptr_t rs_val = get_register(rs);
1905 intptr_t ra_val = (rs_val << shift) >> shift;
1906 set_register(ra, ra_val);
1907 if (instr->Bit(0)) {
1914 int frt = instr->RTValue();
1915 int ra = instr->RAValue();
1916 int rb = instr->RBValue();
1917 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1918 intptr_t rb_val = get_register(rb);
1919 int32_t val = ReadW(ra_val + rb_val);
1920 float* fptr =
reinterpret_cast<float*
>(&val);
1921 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 1923 if ((val & 0x7F800000) == 0x7F800000) {
1925 dval = ((dval & 0xC0000000) << 32) | ((dval & 0x40000000) << 31) |
1926 ((dval & 0x40000000) << 30) | ((dval & 0x7FFFFFFF) << 29) | 0x0;
1927 set_d_register(frt, dval);
1929 set_d_register_from_double(frt, static_cast<double>(*fptr));
1932 set_d_register_from_double(frt, static_cast<double>(*fptr));
1934 if (opcode == LFSUX) {
1936 set_register(ra, ra_val + rb_val);
1942 int frt = instr->RTValue();
1943 int ra = instr->RAValue();
1944 int rb = instr->RBValue();
1945 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1946 intptr_t rb_val = get_register(rb);
1947 int64_t dptr = ReadDW(ra_val + rb_val);
1948 set_d_register(frt, dptr);
1949 if (opcode == LFDUX) {
1951 set_register(ra, ra_val + rb_val);
1955 case STFSUX: V8_FALLTHROUGH;
1957 int frs = instr->RSValue();
1958 int ra = instr->RAValue();
1959 int rb = instr->RBValue();
1960 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1961 intptr_t rb_val = get_register(rb);
1962 float frs_val =
static_cast<float>(get_double_from_d_register(frs));
1963 int32_t* p =
reinterpret_cast<int32_t*
>(&frs_val);
1964 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 1967 int64_t dval = get_d_register(frs);
1968 if ((dval & 0x7FF0000000000000) == 0x7FF0000000000000) {
1969 sval = ((dval & 0xC000000000000000) >> 32) |
1970 ((dval & 0x07FFFFFFE0000000) >> 29);
1973 p =
reinterpret_cast<int32_t*
>(&frs_val);
1976 p =
reinterpret_cast<int32_t*
>(&frs_val);
1978 WriteW(ra_val + rb_val, *p);
1979 if (opcode == STFSUX) {
1981 set_register(ra, ra_val + rb_val);
1985 case STFDUX: V8_FALLTHROUGH;
1987 int frs = instr->RSValue();
1988 int ra = instr->RAValue();
1989 int rb = instr->RBValue();
1990 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1991 intptr_t rb_val = get_register(rb);
1992 int64_t frs_val = get_d_register(frs);
1993 WriteDW(ra_val + rb_val, frs_val);
1994 if (opcode == STFDUX) {
1996 set_register(ra, ra_val + rb_val);
2001 int rs = instr->RSValue();
2002 int ra = instr->RAValue();
2007 for (; n < 32; n++) {
2008 if (bit & rs_val) count++;
2011 set_register(ra, count);
2014 #if V8_TARGET_ARCH_PPC64 2016 int rs = instr->RSValue();
2017 int ra = instr->RAValue();
2022 for (; n < 64; n++) {
2023 if (bit & rs_val) count++;
2026 set_register(ra, count);
2032 __sync_synchronize();
2042 int ra = instr->RAValue();
2043 int rt = instr->RTValue();
2044 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2045 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2046 set_register(rt, ReadWU(ra_val + offset));
2047 if (opcode == LWZU) {
2049 set_register(ra, ra_val + offset);
2056 int ra = instr->RAValue();
2057 int rt = instr->RTValue();
2058 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2059 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2060 set_register(rt, ReadB(ra_val + offset) & 0xFF);
2061 if (opcode == LBZU) {
2063 set_register(ra, ra_val + offset);
2070 int ra = instr->RAValue();
2071 int rs = instr->RSValue();
2072 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2073 int32_t rs_val = get_register(rs);
2074 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2075 WriteW(ra_val + offset, rs_val);
2076 if (opcode == STWU) {
2078 set_register(ra, ra_val + offset);
2083 int ra = instr->RAValue();
2084 int rs = instr->RSValue();
2085 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
2086 intptr_t rs_val = get_register(rs);
2087 intptr_t result = rs_val >> sh;
2088 set_register(ra, result);
2089 if (instr->Bit(0)) {
2095 int rs = instr->RSValue();
2096 int ra = instr->RAValue();
2097 int rb = instr->RBValue();
2098 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2099 int8_t rs_val = get_register(rs);
2100 intptr_t rb_val = get_register(rb);
2101 SetCR0(WriteExB(ra_val + rb_val, rs_val));
2105 int rs = instr->RSValue();
2106 int ra = instr->RAValue();
2107 int rb = instr->RBValue();
2108 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2109 int16_t rs_val = get_register(rs);
2110 intptr_t rb_val = get_register(rb);
2111 SetCR0(WriteExH(ra_val + rb_val, rs_val));
2115 int rs = instr->RSValue();
2116 int ra = instr->RAValue();
2117 int rb = instr->RBValue();
2118 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2119 int32_t rs_val = get_register(rs);
2120 intptr_t rb_val = get_register(rb);
2121 SetCR0(WriteExW(ra_val + rb_val, rs_val));
2125 int rs = instr->RSValue();
2126 int ra = instr->RAValue();
2127 int rb = instr->RBValue();
2128 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2129 int64_t rs_val = get_register(rs);
2130 intptr_t rb_val = get_register(rb);
2131 SetCR0(WriteExDW(ra_val + rb_val, rs_val));
2136 SoftwareInterrupt(instr);
2140 int ra = instr->RAValue();
2141 int rb = instr->RBValue();
2142 int cr = instr->Bits(25, 23);
2144 #if V8_TARGET_ARCH_PPC64 2145 int L = instr->Bit(21);
2148 intptr_t ra_val = get_register(ra);
2149 intptr_t rb_val = get_register(rb);
2150 if (ra_val < rb_val) {
2153 if (ra_val > rb_val) {
2156 if (ra_val == rb_val) {
2159 #if V8_TARGET_ARCH_PPC64 2161 int32_t ra_val = get_register(ra);
2162 int32_t rb_val = get_register(rb);
2163 if (ra_val < rb_val) {
2166 if (ra_val > rb_val) {
2169 if (ra_val == rb_val) {
2174 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
2175 uint32_t condition = bf >> (cr * 4);
2176 condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
2180 int rt = instr->RTValue();
2181 int ra = instr->RAValue();
2182 int rb = instr->RBValue();
2186 uintptr_t alu_out = ~ra_val + rb_val + 1;
2188 if (ra_val <= rb_val) {
2189 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
2191 special_reg_xer_ &= ~0xF0000000;
2193 set_register(rt, alu_out);
2194 if (instr->Bit(0)) {
2201 int rt = instr->RTValue();
2202 int ra = instr->RAValue();
2203 int rb = instr->RBValue();
2208 if (special_reg_xer_ & 0x20000000) {
2211 set_register(rt, alu_out);
2212 if (instr->Bit(0)) {
2213 SetCR0(static_cast<intptr_t>(alu_out));
2219 int rt = instr->RTValue();
2220 int ra = instr->RAValue();
2221 int rb = instr->RBValue();
2227 if (~ra_val < rb_val) {
2228 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
2230 special_reg_xer_ &= ~0xF0000000;
2232 set_register(rt, alu_out);
2233 if (instr->Bit(0)) {
2234 SetCR0(static_cast<intptr_t>(alu_out));
2240 int rt = instr->RTValue();
2241 int ra = instr->RAValue();
2242 int rb = instr->RBValue();
2247 if (special_reg_xer_ & 0x20000000) {
2250 set_register(rt, alu_out);
2251 if (instr->Bit(0)) {
2252 SetCR0(static_cast<intptr_t>(alu_out));
2258 int rt = instr->RTValue();
2259 int ra = instr->RAValue();
2260 int rb = instr->RBValue();
2261 int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2262 int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2265 set_register(rt, alu_out);
2266 if (instr->Bit(0)) {
2267 SetCR0(static_cast<intptr_t>(alu_out));
2272 int rt = instr->RTValue();
2273 int ra = instr->RAValue();
2274 int rb = instr->RBValue();
2275 uint32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2276 uint32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2277 uint64_t alu_out = (uint64_t)ra_val * (uint64_t)rb_val;
2279 set_register(rt, alu_out);
2280 if (instr->Bit(0)) {
2281 SetCR0(static_cast<intptr_t>(alu_out));
2286 int rt = instr->RTValue();
2287 int ra = instr->RAValue();
2288 intptr_t ra_val = get_register(ra);
2289 intptr_t alu_out = 1 + ~ra_val;
2290 #if V8_TARGET_ARCH_PPC64 2292 intptr_t kOverflowVal = (one << 63);
2294 intptr_t kOverflowVal = kMinInt;
2296 set_register(rt, alu_out);
2297 if (instr->Bit(10)) {
2298 if (ra_val == kOverflowVal) {
2299 special_reg_xer_ |= 0xC0000000;
2301 special_reg_xer_ &= ~0x40000000;
2304 if (instr->Bit(0)) {
2305 bool setSO = (special_reg_xer_ & 0x80000000);
2306 SetCR0(alu_out, setSO);
2311 int rs = instr->RSValue();
2312 int ra = instr->RAValue();
2313 int rb = instr->RBValue();
2314 uint32_t rs_val = get_register(rs);
2315 uintptr_t rb_val = get_register(rb) & 0x3F;
2316 uint32_t result = (rb_val > 31) ? 0 : rs_val << rb_val;
2317 set_register(ra, result);
2318 if (instr->Bit(0)) {
2323 #if V8_TARGET_ARCH_PPC64 2325 int rs = instr->RSValue();
2326 int ra = instr->RAValue();
2327 int rb = instr->RBValue();
2329 uintptr_t rb_val = get_register(rb) & 0x7F;
2330 uintptr_t result = (rb_val > 63) ? 0 : rs_val << rb_val;
2331 set_register(ra, result);
2332 if (instr->Bit(0)) {
2338 DCHECK(!instr->Bit(0));
2339 int frt = instr->RTValue();
2340 int ra = instr->RAValue();
2341 int64_t frt_val = get_d_register(frt);
2342 set_register(ra, frt_val);
2346 DCHECK(!instr->Bit(0));
2347 int frt = instr->RTValue();
2348 int ra = instr->RAValue();
2349 int64_t frt_val = get_d_register(frt);
2350 set_register(ra, static_cast<uint32_t>(frt_val));
2354 DCHECK(!instr->Bit(0));
2355 int frt = instr->RTValue();
2356 int ra = instr->RAValue();
2357 int64_t ra_val = get_register(ra);
2358 set_d_register(frt, ra_val);
2362 DCHECK(!instr->Bit(0));
2363 int frt = instr->RTValue();
2364 int ra = instr->RAValue();
2365 int64_t ra_val =
static_cast<int32_t
>(get_register(ra));
2366 set_d_register(frt, ra_val);
2370 DCHECK(!instr->Bit(0));
2371 int frt = instr->RTValue();
2372 int ra = instr->RAValue();
2373 uint64_t ra_val =
static_cast<uint32_t>(get_register(ra));
2374 set_d_register(frt, ra_val);
2379 int rs = instr->RSValue();
2380 int ra = instr->RAValue();
2385 for (; n < 32; n++) {
2386 if (bit & rs_val)
break;
2390 set_register(ra, count);
2391 if (instr->Bit(0)) {
2399 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2403 #if V8_TARGET_ARCH_PPC64 2405 int rs = instr->RSValue();
2406 int ra = instr->RAValue();
2411 for (; n < 64; n++) {
2412 if (bit & rs_val)
break;
2416 set_register(ra, count);
2417 if (instr->Bit(0)) {
2425 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2431 int rs = instr->RSValue();
2432 int ra = instr->RAValue();
2433 int rb = instr->RBValue();
2434 intptr_t rs_val = get_register(rs);
2435 intptr_t rb_val = get_register(rb);
2436 intptr_t alu_out = rs_val & rb_val;
2437 set_register(ra, alu_out);
2438 if (instr->Bit(0)) {
2444 int rs = instr->RSValue();
2445 int ra = instr->RAValue();
2446 int rb = instr->RBValue();
2447 intptr_t rs_val = get_register(rs);
2448 intptr_t rb_val = get_register(rb);
2449 intptr_t alu_out = rs_val & ~rb_val;
2450 set_register(ra, alu_out);
2451 if (instr->Bit(0)) {
2457 int ra = instr->RAValue();
2458 int rb = instr->RBValue();
2459 int cr = instr->Bits(25, 23);
2461 #if V8_TARGET_ARCH_PPC64 2462 int L = instr->Bit(21);
2467 if (ra_val < rb_val) {
2470 if (ra_val > rb_val) {
2473 if (ra_val == rb_val) {
2476 #if V8_TARGET_ARCH_PPC64 2478 uint32_t ra_val = get_register(ra);
2479 uint32_t rb_val = get_register(rb);
2480 if (ra_val < rb_val) {
2483 if (ra_val > rb_val) {
2486 if (ra_val == rb_val) {
2491 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
2492 uint32_t condition = bf >> (cr * 4);
2493 condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
2497 int rt = instr->RTValue();
2498 int ra = instr->RAValue();
2499 int rb = instr->RBValue();
2501 intptr_t ra_val = get_register(ra);
2502 intptr_t rb_val = get_register(rb);
2503 intptr_t alu_out = rb_val - ra_val;
2505 set_register(rt, alu_out);
2506 if (instr->Bit(0)) {
2513 int rt = instr->RTValue();
2514 int ra = instr->RAValue();
2515 intptr_t ra_val = get_register(ra);
2516 if (special_reg_xer_ & 0x20000000) {
2519 set_register(rt, ra_val);
2520 if (instr->Bit(0)) {
2527 int rs = instr->RSValue();
2528 int ra = instr->RAValue();
2529 int rb = instr->RBValue();
2530 intptr_t rs_val = get_register(rs);
2531 intptr_t rb_val = get_register(rb);
2532 intptr_t alu_out = ~(rs_val | rb_val);
2533 set_register(ra, alu_out);
2534 if (instr->Bit(0)) {
2540 int rt = instr->RTValue();
2541 int ra = instr->RAValue();
2542 int rb = instr->RBValue();
2543 int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2544 int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2545 int32_t alu_out = ra_val * rb_val;
2546 set_register(rt, alu_out);
2547 if (instr->Bit(0)) {
2553 #if V8_TARGET_ARCH_PPC64 2555 int rt = instr->RTValue();
2556 int ra = instr->RAValue();
2557 int rb = instr->RBValue();
2558 int64_t ra_val = get_register(ra);
2559 int64_t rb_val = get_register(rb);
2560 int64_t alu_out = ra_val * rb_val;
2561 set_register(rt, alu_out);
2562 if (instr->Bit(0)) {
2570 int rt = instr->RTValue();
2571 int ra = instr->RAValue();
2572 int rb = instr->RBValue();
2573 int32_t ra_val = get_register(ra);
2574 int32_t rb_val = get_register(rb);
2575 bool overflow = (ra_val == kMinInt && rb_val == -1);
2578 int32_t alu_out = (rb_val == 0 || overflow) ? -1 : ra_val / rb_val;
2579 set_register(rt, alu_out);
2580 if (instr->Bit(10)) {
2582 special_reg_xer_ |= 0xC0000000;
2584 special_reg_xer_ &= ~0x40000000;
2587 if (instr->Bit(0)) {
2588 bool setSO = (special_reg_xer_ & 0x80000000);
2589 SetCR0(alu_out, setSO);
2594 int rt = instr->RTValue();
2595 int ra = instr->RAValue();
2596 int rb = instr->RBValue();
2597 uint32_t ra_val = get_register(ra);
2598 uint32_t rb_val = get_register(rb);
2599 bool overflow = (rb_val == 0);
2601 uint32_t alu_out = (overflow) ? -1 : ra_val / rb_val;
2602 set_register(rt, alu_out);
2603 if (instr->Bit(10)) {
2605 special_reg_xer_ |= 0xC0000000;
2607 special_reg_xer_ &= ~0x40000000;
2610 if (instr->Bit(0)) {
2611 bool setSO = (special_reg_xer_ & 0x80000000);
2612 SetCR0(alu_out, setSO);
2616 #if V8_TARGET_ARCH_PPC64 2618 int rt = instr->RTValue();
2619 int ra = instr->RAValue();
2620 int rb = instr->RBValue();
2621 int64_t ra_val = get_register(ra);
2622 int64_t rb_val = get_register(rb);
2624 int64_t kMinLongLong = (one << 63);
2628 (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1))
2631 set_register(rt, alu_out);
2632 if (instr->Bit(0)) {
2639 int rt = instr->RTValue();
2640 int ra = instr->RAValue();
2641 int rb = instr->RBValue();
2642 uint64_t ra_val = get_register(ra);
2643 uint64_t rb_val = get_register(rb);
2645 uint64_t alu_out = (rb_val == 0) ? -1 : ra_val / rb_val;
2646 set_register(rt, alu_out);
2647 if (instr->Bit(0)) {
2655 int rt = instr->RTValue();
2656 int ra = instr->RAValue();
2657 int rb = instr->RBValue();
2659 intptr_t ra_val = get_register(ra);
2660 intptr_t rb_val = get_register(rb);
2661 intptr_t alu_out = ra_val + rb_val;
2662 set_register(rt, alu_out);
2663 if (instr->Bit(0)) {
2670 int rs = instr->RSValue();
2671 int ra = instr->RAValue();
2672 int rb = instr->RBValue();
2673 intptr_t rs_val = get_register(rs);
2674 intptr_t rb_val = get_register(rb);
2675 intptr_t alu_out = rs_val ^ rb_val;
2676 set_register(ra, alu_out);
2677 if (instr->Bit(0)) {
2683 int rs = instr->RSValue();
2684 int ra = instr->RAValue();
2685 int rb = instr->RBValue();
2686 intptr_t rs_val = get_register(rs);
2687 intptr_t rb_val = get_register(rb);
2688 intptr_t alu_out = rs_val | rb_val;
2689 set_register(ra, alu_out);
2690 if (instr->Bit(0)) {
2696 int rs = instr->RSValue();
2697 int ra = instr->RAValue();
2698 int rb = instr->RBValue();
2699 intptr_t rs_val = get_register(rs);
2700 intptr_t rb_val = get_register(rb);
2701 intptr_t alu_out = rs_val | ~rb_val;
2702 set_register(ra, alu_out);
2703 if (instr->Bit(0)) {
2709 int rt = instr->RTValue();
2710 int spr = instr->Bits(20, 11);
2714 set_register(rt, special_reg_lr_);
2718 int rt = instr->RTValue();
2719 intptr_t rt_val = get_register(rt);
2720 int spr = instr->Bits(20, 11);
2722 special_reg_lr_ = rt_val;
2723 }
else if (spr == 288) {
2724 special_reg_ctr_ = rt_val;
2725 }
else if (spr == 32) {
2726 special_reg_xer_ = rt_val;
2733 int rt = instr->RTValue();
2734 set_register(rt, condition_reg_);
2739 int rs = instr->RSValue();
2740 int ra = instr->RAValue();
2741 int rb = instr->RBValue();
2742 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2743 int32_t rs_val = get_register(rs);
2744 intptr_t rb_val = get_register(rb);
2745 WriteW(ra_val + rb_val, rs_val);
2746 if (opcode == STWUX) {
2748 set_register(ra, ra_val + rb_val);
2754 int rs = instr->RSValue();
2755 int ra = instr->RAValue();
2756 int rb = instr->RBValue();
2757 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2758 int8_t rs_val = get_register(rs);
2759 intptr_t rb_val = get_register(rb);
2760 WriteB(ra_val + rb_val, rs_val);
2761 if (opcode == STBUX) {
2763 set_register(ra, ra_val + rb_val);
2769 int rs = instr->RSValue();
2770 int ra = instr->RAValue();
2771 int rb = instr->RBValue();
2772 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2773 int16_t rs_val = get_register(rs);
2774 intptr_t rb_val = get_register(rb);
2775 WriteH(ra_val + rb_val, rs_val);
2776 if (opcode == STHUX) {
2778 set_register(ra, ra_val + rb_val);
2784 int rt = instr->RTValue();
2785 int ra = instr->RAValue();
2786 int rb = instr->RBValue();
2787 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2788 intptr_t rb_val = get_register(rb);
2789 set_register(rt, ReadWU(ra_val + rb_val));
2790 if (opcode == LWZUX) {
2791 DCHECK(ra != 0 && ra != rt);
2792 set_register(ra, ra_val + rb_val);
2796 #if V8_TARGET_ARCH_PPC64 2798 int rt = instr->RTValue();
2799 int ra = instr->RAValue();
2800 int rb = instr->RBValue();
2801 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2802 intptr_t rb_val = get_register(rb);
2803 set_register(rt, ReadW(ra_val + rb_val));
2808 int rt = instr->RTValue();
2809 int ra = instr->RAValue();
2810 int rb = instr->RBValue();
2811 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2812 intptr_t rb_val = get_register(rb);
2813 intptr_t result = ReadDW(ra_val + rb_val);
2814 set_register(rt, result);
2815 if (opcode == LDUX) {
2816 DCHECK(ra != 0 && ra != rt);
2817 set_register(ra, ra_val + rb_val);
2823 int rs = instr->RSValue();
2824 int ra = instr->RAValue();
2825 int rb = instr->RBValue();
2826 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2827 intptr_t rs_val = get_register(rs);
2828 intptr_t rb_val = get_register(rb);
2829 WriteDW(ra_val + rb_val, rs_val);
2830 if (opcode == STDUX) {
2832 set_register(ra, ra_val + rb_val);
2839 int rt = instr->RTValue();
2840 int ra = instr->RAValue();
2841 int rb = instr->RBValue();
2842 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2843 intptr_t rb_val = get_register(rb);
2844 set_register(rt, ReadBU(ra_val + rb_val) & 0xFF);
2845 if (opcode == LBZUX) {
2846 DCHECK(ra != 0 && ra != rt);
2847 set_register(ra, ra_val + rb_val);
2853 int rt = instr->RTValue();
2854 int ra = instr->RAValue();
2855 int rb = instr->RBValue();
2856 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2857 intptr_t rb_val = get_register(rb);
2858 set_register(rt, ReadHU(ra_val + rb_val) & 0xFFFF);
2859 if (opcode == LHZUX) {
2860 DCHECK(ra != 0 && ra != rt);
2861 set_register(ra, ra_val + rb_val);
2866 int rt = instr->RTValue();
2867 int ra = instr->RAValue();
2868 int rb = instr->RBValue();
2869 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2870 intptr_t rb_val = get_register(rb);
2871 set_register(rt, ReadH(ra_val + rb_val));
2875 int rt = instr->RTValue();
2876 int ra = instr->RAValue();
2877 int rb = instr->RBValue();
2878 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2879 intptr_t rb_val = get_register(rb);
2880 set_register(rt, ReadExBU(ra_val + rb_val) & 0xFF);
2884 int rt = instr->RTValue();
2885 int ra = instr->RAValue();
2886 int rb = instr->RBValue();
2887 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2888 intptr_t rb_val = get_register(rb);
2889 set_register(rt, ReadExHU(ra_val + rb_val));
2893 int rt = instr->RTValue();
2894 int ra = instr->RAValue();
2895 int rb = instr->RBValue();
2896 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2897 intptr_t rb_val = get_register(rb);
2898 set_register(rt, ReadExWU(ra_val + rb_val));
2902 int rt = instr->RTValue();
2903 int ra = instr->RAValue();
2904 int rb = instr->RBValue();
2905 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2906 intptr_t rb_val = get_register(rb);
2907 set_register(rt, ReadExDWU(ra_val + rb_val));
2915 int rt = instr->RTValue();
2916 int ra = instr->RAValue();
2917 int rb = instr->RBValue();
2918 int condition_bit = instr->RCValue();
2919 int condition_mask = 0x80000000 >> condition_bit;
2920 intptr_t ra_val = (ra == 0) ? 0 : get_register(ra);
2921 intptr_t rb_val = get_register(rb);
2922 intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val;
2923 set_register(rt, value);
2929 int ra = instr->RAValue();
2930 int rs = instr->RSValue();
2931 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2932 int8_t rs_val = get_register(rs);
2933 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2934 WriteB(ra_val + offset, rs_val);
2935 if (opcode == STBU) {
2937 set_register(ra, ra_val + offset);
2944 int ra = instr->RAValue();
2945 int rt = instr->RTValue();
2946 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2947 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2948 uintptr_t result = ReadHU(ra_val + offset) & 0xFFFF;
2949 set_register(rt, result);
2950 if (opcode == LHZU) {
2951 set_register(ra, ra_val + offset);
2958 int ra = instr->RAValue();
2959 int rt = instr->RTValue();
2960 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2961 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2962 intptr_t result = ReadH(ra_val + offset);
2963 set_register(rt, result);
2964 if (opcode == LHAU) {
2965 set_register(ra, ra_val + offset);
2972 int ra = instr->RAValue();
2973 int rs = instr->RSValue();
2974 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2975 int16_t rs_val = get_register(rs);
2976 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2977 WriteH(ra_val + offset, rs_val);
2978 if (opcode == STHU) {
2980 set_register(ra, ra_val + offset);
2993 int frt = instr->RTValue();
2994 int ra = instr->RAValue();
2995 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
2996 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2997 int32_t val = ReadW(ra_val + offset);
2998 float* fptr =
reinterpret_cast<float*
>(&val);
2999 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 3001 if ((val & 0x7F800000) == 0x7F800000) {
3003 dval = ((dval & 0xC0000000) << 32) | ((dval & 0x40000000) << 31) |
3004 ((dval & 0x40000000) << 30) | ((dval & 0x7FFFFFFF) << 29) | 0x0;
3005 set_d_register(frt, dval);
3007 set_d_register_from_double(frt, static_cast<double>(*fptr));
3010 set_d_register_from_double(frt, static_cast<double>(*fptr));
3012 if (opcode == LFSU) {
3014 set_register(ra, ra_val + offset);
3021 int frt = instr->RTValue();
3022 int ra = instr->RAValue();
3023 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3024 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3025 int64_t dptr = ReadDW(ra_val + offset);
3026 set_d_register(frt, dptr);
3027 if (opcode == LFDU) {
3029 set_register(ra, ra_val + offset);
3034 case STFSU: V8_FALLTHROUGH;
3036 int frs = instr->RSValue();
3037 int ra = instr->RAValue();
3038 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3039 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3040 float frs_val =
static_cast<float>(get_double_from_d_register(frs));
3042 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 3045 int64_t dval = get_d_register(frs);
3046 if ((dval & 0x7FF0000000000000) == 0x7FF0000000000000) {
3047 sval = ((dval & 0xC000000000000000) >> 32) |
3048 ((dval & 0x07FFFFFFE0000000) >> 29);
3051 p =
reinterpret_cast<int32_t*
>(&frs_val);
3054 p =
reinterpret_cast<int32_t*
>(&frs_val);
3056 WriteW(ra_val + offset, *p);
3057 if (opcode == STFSU) {
3059 set_register(ra, ra_val + offset);
3065 int frs = instr->RSValue();
3066 int ra = instr->RAValue();
3067 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
3068 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3069 int64_t frs_val = get_d_register(frs);
3070 WriteDW(ra_val + offset, frs_val);
3071 if (opcode == STFDU) {
3073 set_register(ra, ra_val + offset);
3080 int frt = instr->RTValue();
3081 int frb = instr->RBValue();
3082 int64_t frb_val = get_d_register(frb);
3083 double frt_val =
static_cast<float>(frb_val);
3084 set_d_register_from_double(frt, frt_val);
3089 int frt = instr->RTValue();
3090 int frb = instr->RBValue();
3091 uint64_t frb_val = get_d_register(frb);
3092 double frt_val =
static_cast<float>(frb_val);
3093 set_d_register_from_double(frt, frt_val);
3098 int frt = instr->RTValue();
3099 int fra = instr->RAValue();
3100 int frb = instr->RBValue();
3101 double fra_val = get_double_from_d_register(fra);
3102 double frb_val = get_double_from_d_register(frb);
3103 double frt_val = fra_val / frb_val;
3104 set_d_register_from_double(frt, frt_val);
3108 int frt = instr->RTValue();
3109 int fra = instr->RAValue();
3110 int frb = instr->RBValue();
3111 double fra_val = get_double_from_d_register(fra);
3112 double frb_val = get_double_from_d_register(frb);
3113 double frt_val = fra_val - frb_val;
3114 set_d_register_from_double(frt, frt_val);
3118 int frt = instr->RTValue();
3119 int fra = instr->RAValue();
3120 int frb = instr->RBValue();
3121 double fra_val = get_double_from_d_register(fra);
3122 double frb_val = get_double_from_d_register(frb);
3123 double frt_val = fra_val + frb_val;
3124 set_d_register_from_double(frt, frt_val);
3128 lazily_initialize_fast_sqrt();
3129 int frt = instr->RTValue();
3130 int frb = instr->RBValue();
3131 double frb_val = get_double_from_d_register(frb);
3132 double frt_val = fast_sqrt(frb_val);
3133 set_d_register_from_double(frt, frt_val);
3137 int frt = instr->RTValue();
3138 int fra = instr->RAValue();
3139 int frb = instr->RBValue();
3140 int frc = instr->RCValue();
3141 double fra_val = get_double_from_d_register(fra);
3142 double frb_val = get_double_from_d_register(frb);
3143 double frc_val = get_double_from_d_register(frc);
3144 double frt_val = ((fra_val >= 0.0) ? frc_val : frb_val);
3145 set_d_register_from_double(frt, frt_val);
3149 int frt = instr->RTValue();
3150 int fra = instr->RAValue();
3151 int frc = instr->RCValue();
3152 double fra_val = get_double_from_d_register(fra);
3153 double frc_val = get_double_from_d_register(frc);
3154 double frt_val = fra_val * frc_val;
3155 set_d_register_from_double(frt, frt_val);
3159 int frt = instr->RTValue();
3160 int fra = instr->RAValue();
3161 int frb = instr->RBValue();
3162 int frc = instr->RCValue();
3163 double fra_val = get_double_from_d_register(fra);
3164 double frb_val = get_double_from_d_register(frb);
3165 double frc_val = get_double_from_d_register(frc);
3166 double frt_val = (fra_val * frc_val) - frb_val;
3167 set_d_register_from_double(frt, frt_val);
3171 int frt = instr->RTValue();
3172 int fra = instr->RAValue();
3173 int frb = instr->RBValue();
3174 int frc = instr->RCValue();
3175 double fra_val = get_double_from_d_register(fra);
3176 double frb_val = get_double_from_d_register(frb);
3177 double frc_val = get_double_from_d_register(frc);
3178 double frt_val = (fra_val * frc_val) + frb_val;
3179 set_d_register_from_double(frt, frt_val);
3183 int fra = instr->RAValue();
3184 int frb = instr->RBValue();
3185 double fra_val = get_double_from_d_register(fra);
3186 double frb_val = get_double_from_d_register(frb);
3187 int cr = instr->Bits(25, 23);
3189 if (fra_val < frb_val) {
3192 if (fra_val > frb_val) {
3195 if (fra_val == frb_val) {
3198 if (std::isunordered(fra_val, frb_val)) {
3201 int condition_mask = 0xF0000000 >> (cr * 4);
3202 int condition = bf >> (cr * 4);
3203 condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
3207 int frt = instr->RTValue();
3208 int frb = instr->RBValue();
3209 double frb_val = get_double_from_d_register(frb);
3210 double frt_val = std::round(frb_val);
3211 set_d_register_from_double(frt, frt_val);
3212 if (instr->Bit(0)) {
3218 int frt = instr->RTValue();
3219 int frb = instr->RBValue();
3220 double frb_val = get_double_from_d_register(frb);
3221 double frt_val = std::trunc(frb_val);
3222 set_d_register_from_double(frt, frt_val);
3223 if (instr->Bit(0)) {
3229 int frt = instr->RTValue();
3230 int frb = instr->RBValue();
3231 double frb_val = get_double_from_d_register(frb);
3232 double frt_val = std::ceil(frb_val);
3233 set_d_register_from_double(frt, frt_val);
3234 if (instr->Bit(0)) {
3240 int frt = instr->RTValue();
3241 int frb = instr->RBValue();
3242 double frb_val = get_double_from_d_register(frb);
3243 double frt_val = std::floor(frb_val);
3244 set_d_register_from_double(frt, frt_val);
3245 if (instr->Bit(0)) {
3251 int frt = instr->RTValue();
3252 int frb = instr->RBValue();
3255 double frb_val = get_double_from_d_register(frb);
3256 double frt_val =
static_cast<float>(frb_val);
3257 set_d_register_from_double(frt, frt_val);
3258 if (instr->Bit(0)) {
3264 int frt = instr->RTValue();
3265 int frb = instr->RBValue();
3266 int64_t frb_val = get_d_register(frb);
3267 double frt_val =
static_cast<double>(frb_val);
3268 set_d_register_from_double(frt, frt_val);
3272 int frt = instr->RTValue();
3273 int frb = instr->RBValue();
3274 uint64_t frb_val = get_d_register(frb);
3275 double frt_val =
static_cast<double>(frb_val);
3276 set_d_register_from_double(frt, frt_val);
3281 int frt = instr->RTValue();
3282 int frb = instr->RBValue();
3283 double frb_val = get_double_from_d_register(frb);
3284 int mode = (opcode == FCTIDZ) ? kRoundToZero
3285 : (fp_condition_reg_ & kFPRoundingModeMask);
3288 int64_t kMinVal = (one << 63);
3289 int64_t kMaxVal = kMinVal - 1;
3290 bool invalid_convert =
false;
3292 if (std::isnan(frb_val)) {
3294 invalid_convert =
true;
3298 frb_val = std::trunc(frb_val);
3300 case kRoundToPlusInf:
3301 frb_val = std::ceil(frb_val);
3303 case kRoundToMinusInf:
3304 frb_val = std::floor(frb_val);
3310 if (frb_val < static_cast<double>(kMinVal)) {
3312 invalid_convert =
true;
3313 }
else if (frb_val >= static_cast<double>(kMaxVal)) {
3315 invalid_convert =
true;
3320 set_d_register(frt, frt_val);
3321 if (invalid_convert) SetFPSCR(VXCVI);
3326 int frt = instr->RTValue();
3327 int frb = instr->RBValue();
3328 double frb_val = get_double_from_d_register(frb);
3329 int mode = (opcode == FCTIDUZ)
3331 : (fp_condition_reg_ & kFPRoundingModeMask);
3333 uint64_t kMinVal = 0;
3334 uint64_t kMaxVal = kMinVal - 1;
3335 bool invalid_convert =
false;
3337 if (std::isnan(frb_val)) {
3339 invalid_convert =
true;
3343 frb_val = std::trunc(frb_val);
3345 case kRoundToPlusInf:
3346 frb_val = std::ceil(frb_val);
3348 case kRoundToMinusInf:
3349 frb_val = std::floor(frb_val);
3355 if (frb_val < static_cast<double>(kMinVal)) {
3357 invalid_convert =
true;
3358 }
else if (frb_val >= static_cast<double>(kMaxVal)) {
3360 invalid_convert =
true;
3362 frt_val = (uint64_t)frb_val;
3365 set_d_register(frt, frt_val);
3366 if (invalid_convert) SetFPSCR(VXCVI);
3371 int frt = instr->RTValue();
3372 int frb = instr->RBValue();
3373 double frb_val = get_double_from_d_register(frb);
3374 int mode = (opcode == FCTIWZ) ? kRoundToZero
3375 : (fp_condition_reg_ & kFPRoundingModeMask);
3380 if (std::isnan(frb_val)) {
3385 frb_val = std::trunc(frb_val);
3387 case kRoundToPlusInf:
3388 frb_val = std::ceil(frb_val);
3390 case kRoundToMinusInf:
3391 frb_val = std::floor(frb_val);
3393 case kRoundToNearest: {
3394 double orig = frb_val;
3395 frb_val = lround(frb_val);
3397 if (std::fabs(frb_val - orig) == 0.5 && ((
int64_t)frb_val % 2)) {
3398 frb_val += ((frb_val > 0) ? -1.0 : 1.0);
3406 if (frb_val < kMinVal) {
3408 }
else if (frb_val > kMaxVal) {
3414 set_d_register(frt, frt_val);
3418 int frt = instr->RTValue();
3419 int frb = instr->RBValue();
3420 double frb_val = get_double_from_d_register(frb);
3421 double frt_val = -frb_val;
3422 set_d_register_from_double(frt, frt_val);
3426 int frt = instr->RTValue();
3427 int frb = instr->RBValue();
3428 int64_t frb_val = get_d_register(frb);
3429 set_d_register(frt, frb_val);
3433 int bf = instr->Bits(25, 23);
3434 int imm = instr->Bits(15, 12);
3435 int fp_condition_mask = 0xF0000000 >> (bf * 4);
3436 fp_condition_reg_ &= ~fp_condition_mask;
3437 fp_condition_reg_ |= (imm << (28 - (bf * 4)));
3438 if (instr->Bit(0)) {
3439 condition_reg_ &= 0xF0FFFFFF;
3440 condition_reg_ |= (imm << 23);
3445 int frb = instr->RBValue();
3446 int64_t frb_dval = get_d_register(frb);
3447 int32_t frb_ival =
static_cast<int32_t
>((frb_dval)&0xFFFFFFFF);
3448 int l = instr->Bits(25, 25);
3450 fp_condition_reg_ = frb_ival;
3454 if (instr->Bit(0)) {
3462 int frt = instr->RTValue();
3464 set_d_register(frt, lval);
3468 int bf = instr->Bits(25, 23);
3469 int bfa = instr->Bits(20, 18);
3470 int cr_shift = (7 - bf) * CRWIDTH;
3471 int fp_shift = (7 - bfa) * CRWIDTH;
3472 int field_val = (fp_condition_reg_ >> fp_shift) & 0xF;
3473 condition_reg_ &= ~(0x0F << cr_shift);
3474 condition_reg_ |= (field_val << cr_shift);
3489 int bt = instr->Bits(25, 21);
3491 if (instr->Bit(0)) {
3497 int bt = instr->Bits(25, 21);
3499 if (instr->Bit(0)) {
3505 int frt = instr->RTValue();
3506 int frb = instr->RBValue();
3507 double frb_val = get_double_from_d_register(frb);
3508 double frt_val = std::fabs(frb_val);
3509 set_d_register_from_double(frt, frt_val);
3514 #if V8_TARGET_ARCH_PPC64 3516 int ra = instr->RAValue();
3517 int rs = instr->RSValue();
3519 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3520 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3521 DCHECK(sh >= 0 && sh <= 63);
3522 DCHECK(mb >= 0 && mb <= 63);
3523 uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3524 uintptr_t mask = 0xFFFFFFFFFFFFFFFF >> mb;
3526 set_register(ra, result);
3527 if (instr->Bit(0)) {
3533 int ra = instr->RAValue();
3534 int rs = instr->RSValue();
3536 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3537 int me = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3538 DCHECK(sh >= 0 && sh <= 63);
3539 DCHECK(me >= 0 && me <= 63);
3540 uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3541 uintptr_t mask = 0xFFFFFFFFFFFFFFFF << (63 - me);
3543 set_register(ra, result);
3544 if (instr->Bit(0)) {
3550 int ra = instr->RAValue();
3551 int rs = instr->RSValue();
3553 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3554 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3555 DCHECK(sh >= 0 && sh <= 63);
3556 DCHECK(mb >= 0 && mb <= 63);
3557 uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3558 uintptr_t mask = (0xFFFFFFFFFFFFFFFF >> mb) & (0xFFFFFFFFFFFFFFFF << sh);
3560 set_register(ra, result);
3561 if (instr->Bit(0)) {
3567 int ra = instr->RAValue();
3568 int rs = instr->RSValue();
3570 intptr_t ra_val = get_register(ra);
3571 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
3572 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3574 uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3577 uintptr_t bit = 0x8000000000000000 >> mb;
3578 for (; mb <= me; mb++) {
3582 }
else if (mb == me + 1) {
3583 mask = 0xFFFFFFFFFFFFFFFF;
3585 uintptr_t bit = 0x8000000000000000 >> (me + 1);
3586 mask = 0xFFFFFFFFFFFFFFFF;
3587 for (; me < mb; me++) {
3595 set_register(ra, result);
3596 if (instr->Bit(0)) {
3602 int ra = instr->RAValue();
3603 int rs = instr->RSValue();
3604 int rb = instr->RBValue();
3607 int sh = (rb_val & 0x3F);
3608 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
3609 DCHECK(sh >= 0 && sh <= 63);
3610 DCHECK(mb >= 0 && mb <= 63);
3611 uintptr_t result = base::bits::RotateLeft64(rs_val, sh);
3612 uintptr_t mask = 0xFFFFFFFFFFFFFFFF >> mb;
3614 set_register(ra, result);
3615 if (instr->Bit(0)) {
3624 int ra = instr->RAValue();
3625 int rt = instr->RTValue();
3626 int64_t ra_val = ra == 0 ? 0 : get_register(ra);
3627 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
3628 switch (instr->Bits(1, 0)) {
3630 intptr_t result = ReadDW(ra_val + offset);
3631 set_register(rt, result);
3635 intptr_t result = ReadDW(ra_val + offset);
3636 set_register(rt, result);
3638 set_register(ra, ra_val + offset);
3642 intptr_t result = ReadW(ra_val + offset);
3643 set_register(rt, result);
3652 int ra = instr->RAValue();
3653 int rs = instr->RSValue();
3654 int64_t ra_val = ra == 0 ? 0 : get_register(ra);
3655 int64_t rs_val = get_register(rs);
3656 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
3657 WriteDW(ra_val + offset, rs_val);
3658 if (opcode == STDU) {
3660 set_register(ra, ra_val + offset);
3667 int frt = instr->RTValue();
3668 int fra = instr->RAValue();
3669 int frb = instr->RBValue();
3670 double fra_val = get_double_from_d_register(fra);
3671 double frb_val = get_double_from_d_register(frb);
3672 double frt_val = fra_val + frb_val;
3673 set_d_register_from_double(frt, frt_val);
3677 int frt = instr->RTValue();
3678 int fra = instr->RAValue();
3679 int frb = instr->RBValue();
3680 double fra_val = get_double_from_d_register(fra);
3681 double frb_val = get_double_from_d_register(frb);
3682 double frt_val = fra_val - frb_val;
3683 set_d_register_from_double(frt, frt_val);
3687 int frt = instr->RTValue();
3688 int fra = instr->RAValue();
3689 int frb = instr->RBValue();
3690 double fra_val = get_double_from_d_register(fra);
3691 double frb_val = get_double_from_d_register(frb);
3692 double frt_val = fra_val * frb_val;
3693 set_d_register_from_double(frt, frt_val);
3697 int frt = instr->RTValue();
3698 int fra = instr->RAValue();
3699 int frb = instr->RBValue();
3700 double fra_val = get_double_from_d_register(fra);
3701 double frb_val = get_double_from_d_register(frb);
3702 double frt_val = fra_val / frb_val;
3703 set_d_register_from_double(frt, frt_val);
3715 void Simulator::Trace(Instruction* instr) {
3720 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
3721 PrintF(
"%05d %08" V8PRIxPTR
" %s\n", icount_,
3722 reinterpret_cast<intptr_t>(instr), buffer.start());
3727 void Simulator::ExecuteInstruction(Instruction* instr) {
3728 if (v8::internal::FLAG_check_icache) {
3729 CheckICache(i_cache(), instr);
3731 pc_modified_ =
false;
3732 if (::v8::internal::FLAG_trace_sim) {
3735 uint32_t opcode = instr->OpcodeField();
3736 if (opcode == TWI) {
3737 SoftwareInterrupt(instr);
3739 ExecuteGeneric(instr);
3741 if (!pc_modified_) {
3742 set_pc(reinterpret_cast<intptr_t>(instr) + kInstrSize);
3746 void Simulator::Execute() {
3749 intptr_t program_counter = get_pc();
3751 if (::v8::internal::FLAG_stop_sim_at == 0) {
3754 while (program_counter != end_sim_pc) {
3755 Instruction* instr =
reinterpret_cast<Instruction*
>(program_counter);
3757 ExecuteInstruction(instr);
3758 program_counter = get_pc();
3763 while (program_counter != end_sim_pc) {
3764 Instruction* instr =
reinterpret_cast<Instruction*
>(program_counter);
3766 if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
3767 PPCDebugger dbg(
this);
3770 ExecuteInstruction(instr);
3772 program_counter = get_pc();
3777 void Simulator::CallInternal(Address entry) {
3779 isolate_->stack_guard()->AdjustStackLimitForSimulator();
3782 if (ABI_USES_FUNCTION_DESCRIPTORS) {
3784 set_pc(*(reinterpret_cast<intptr_t*>(entry)));
3787 set_pc(static_cast<intptr_t>(entry));
3790 if (ABI_CALL_VIA_IP) {
3792 set_register(r12, get_pc());
3798 special_reg_lr_ = end_sim_pc;
3801 intptr_t r2_val = get_register(r2);
3802 intptr_t r13_val = get_register(r13);
3803 intptr_t r14_val = get_register(r14);
3804 intptr_t r15_val = get_register(r15);
3805 intptr_t r16_val = get_register(r16);
3806 intptr_t r17_val = get_register(r17);
3807 intptr_t r18_val = get_register(r18);
3808 intptr_t r19_val = get_register(r19);
3809 intptr_t r20_val = get_register(r20);
3810 intptr_t r21_val = get_register(r21);
3811 intptr_t r22_val = get_register(r22);
3812 intptr_t r23_val = get_register(r23);
3813 intptr_t r24_val = get_register(r24);
3814 intptr_t r25_val = get_register(r25);
3815 intptr_t r26_val = get_register(r26);
3816 intptr_t r27_val = get_register(r27);
3817 intptr_t r28_val = get_register(r28);
3818 intptr_t r29_val = get_register(r29);
3819 intptr_t r30_val = get_register(r30);
3820 intptr_t r31_val = get_register(fp);
3824 intptr_t callee_saved_value = icount_;
3825 set_register(r2, callee_saved_value);
3826 set_register(r13, callee_saved_value);
3827 set_register(r14, callee_saved_value);
3828 set_register(r15, callee_saved_value);
3829 set_register(r16, callee_saved_value);
3830 set_register(r17, callee_saved_value);
3831 set_register(r18, callee_saved_value);
3832 set_register(r19, callee_saved_value);
3833 set_register(r20, callee_saved_value);
3834 set_register(r21, callee_saved_value);
3835 set_register(r22, callee_saved_value);
3836 set_register(r23, callee_saved_value);
3837 set_register(r24, callee_saved_value);
3838 set_register(r25, callee_saved_value);
3839 set_register(r26, callee_saved_value);
3840 set_register(r27, callee_saved_value);
3841 set_register(r28, callee_saved_value);
3842 set_register(r29, callee_saved_value);
3843 set_register(r30, callee_saved_value);
3844 set_register(fp, callee_saved_value);
3850 if (ABI_TOC_REGISTER != 2) {
3851 CHECK_EQ(callee_saved_value, get_register(r2));
3853 if (ABI_TOC_REGISTER != 13) {
3854 CHECK_EQ(callee_saved_value, get_register(r13));
3856 CHECK_EQ(callee_saved_value, get_register(r14));
3857 CHECK_EQ(callee_saved_value, get_register(r15));
3858 CHECK_EQ(callee_saved_value, get_register(r16));
3859 CHECK_EQ(callee_saved_value, get_register(r17));
3860 CHECK_EQ(callee_saved_value, get_register(r18));
3861 CHECK_EQ(callee_saved_value, get_register(r19));
3862 CHECK_EQ(callee_saved_value, get_register(r20));
3863 CHECK_EQ(callee_saved_value, get_register(r21));
3864 CHECK_EQ(callee_saved_value, get_register(r22));
3865 CHECK_EQ(callee_saved_value, get_register(r23));
3866 CHECK_EQ(callee_saved_value, get_register(r24));
3867 CHECK_EQ(callee_saved_value, get_register(r25));
3868 CHECK_EQ(callee_saved_value, get_register(r26));
3869 CHECK_EQ(callee_saved_value, get_register(r27));
3870 CHECK_EQ(callee_saved_value, get_register(r28));
3871 CHECK_EQ(callee_saved_value, get_register(r29));
3872 CHECK_EQ(callee_saved_value, get_register(r30));
3873 CHECK_EQ(callee_saved_value, get_register(fp));
3876 set_register(r2, r2_val);
3877 set_register(r13, r13_val);
3878 set_register(r14, r14_val);
3879 set_register(r15, r15_val);
3880 set_register(r16, r16_val);
3881 set_register(r17, r17_val);
3882 set_register(r18, r18_val);
3883 set_register(r19, r19_val);
3884 set_register(r20, r20_val);
3885 set_register(r21, r21_val);
3886 set_register(r22, r22_val);
3887 set_register(r23, r23_val);
3888 set_register(r24, r24_val);
3889 set_register(r25, r25_val);
3890 set_register(r26, r26_val);
3891 set_register(r27, r27_val);
3892 set_register(r28, r28_val);
3893 set_register(r29, r29_val);
3894 set_register(r30, r30_val);
3895 set_register(fp, r31_val);
3898 intptr_t Simulator::CallImpl(Address entry,
int argument_count,
3899 const intptr_t* arguments) {
3903 int reg_arg_count = std::min(8, argument_count);
3904 int stack_arg_count = argument_count - reg_arg_count;
3905 for (
int i = 0;
i < reg_arg_count;
i++) {
3906 set_register(
i + 3, arguments[
i]);
3910 intptr_t original_stack = get_register(sp);
3912 intptr_t entry_stack =
3914 (kNumRequiredStackFrameSlots + stack_arg_count) *
sizeof(intptr_t));
3915 if (base::OS::ActivationFrameAlignment() != 0) {
3916 entry_stack &= -base::OS::ActivationFrameAlignment();
3920 intptr_t* stack_argument =
3921 reinterpret_cast<intptr_t*
>(entry_stack) + kStackFrameExtraParamSlot;
3922 memcpy(stack_argument, arguments + reg_arg_count,
3923 stack_arg_count *
sizeof(*arguments));
3924 set_register(sp, entry_stack);
3926 CallInternal(entry);
3929 CHECK_EQ(entry_stack, get_register(sp));
3930 set_register(sp, original_stack);
3932 return get_register(r3);
3935 void Simulator::CallFP(Address entry,
double d0,
double d1) {
3936 set_d_register_from_double(1, d0);
3937 set_d_register_from_double(2, d1);
3938 CallInternal(entry);
3941 int32_t Simulator::CallFPReturnsInt(Address entry,
double d0,
double d1) {
3942 CallFP(entry, d0, d1);
3943 int32_t result = get_register(r3);
3947 double Simulator::CallFPReturnsDouble(Address entry,
double d0,
double d1) {
3948 CallFP(entry, d0, d1);
3949 return get_double_from_d_register(1);
3956 *stack_slot = address;
3957 set_register(sp, new_sp);
3963 uintptr_t current_sp = get_register(sp);
3966 set_register(sp, current_sp +
sizeof(
uintptr_t));
3970 Simulator::GlobalMonitor::GlobalMonitor()
3971 : access_state_(MonitorAccess::Open),
3973 size_(TransactionSize::
None),
3974 thread_id_(ThreadId::Invalid()) {}
3976 void Simulator::GlobalMonitor::Clear() {
3977 access_state_ = MonitorAccess::Open;
3979 size_ = TransactionSize::None;
3980 thread_id_ = ThreadId::Invalid();
3983 void Simulator::GlobalMonitor::NotifyLoadExcl(
uintptr_t addr,
3984 TransactionSize size,
3985 ThreadId thread_id) {
3991 access_state_ = MonitorAccess::Exclusive;
3992 tagged_addr_ = addr;
3994 thread_id_ = thread_id;
3997 void Simulator::GlobalMonitor::NotifyStore(
uintptr_t addr, TransactionSize size,
3998 ThreadId thread_id) {
3999 if (access_state_ == MonitorAccess::Exclusive) {
4003 uintptr_t exclusive_transaction_start = tagged_addr_;
4005 tagged_addr_ +
static_cast<uintptr_t>(size_);
4006 bool is_not_overlapped = transaction_end < exclusive_transaction_start ||
4007 exclusive_transaction_end < transaction_start;
4008 if (!is_not_overlapped && !thread_id_.Equals(thread_id)) {
4014 bool Simulator::GlobalMonitor::NotifyStoreExcl(
uintptr_t addr,
4015 TransactionSize size,
4016 ThreadId thread_id) {
4017 bool permission = access_state_ == MonitorAccess::Exclusive &&
4018 addr == tagged_addr_ && size_ == size &&
4019 thread_id_.Equals(thread_id);
4030 #endif // USE_SIMULATOR 4031 #endif // V8_TARGET_ARCH_PPC