7#if defined(USE_SIMULATOR)
37 Simulator::GlobalMonitor::Get)
49 explicit PPCDebugger(Simulator* sim) : sim_(sim) {}
53 static const Instr kBreakpointInstr = (TWI | 0x1F *
B21);
54 static const Instr kNopInstr = (
ORI);
58 intptr_t GetRegisterValue(
int regnum);
59 double GetRegisterPairDoubleValue(
int regnum);
60 double GetFPDoubleRegisterValue(
int regnum);
61 bool GetValue(
const char* desc, intptr_t* value);
62 bool GetFPDoubleValue(
const char* desc,
double* value);
65 bool SetBreakpoint(Instruction* break_pc);
66 void DeleteBreakpoint();
70 void UndoBreakpoint();
71 void RedoBreakpoint();
74void Simulator::DebugAtNextPC() {
75 PrintF(
"Starting debugger on the next instruction:\n");
77 PPCDebugger(
this).Debug();
80intptr_t PPCDebugger::GetRegisterValue(
int regnum) {
81 return sim_->get_register(regnum);
84double PPCDebugger::GetRegisterPairDoubleValue(
int regnum) {
85 return sim_->get_double_from_register_pair(regnum);
88double PPCDebugger::GetFPDoubleRegisterValue(
int regnum) {
89 return sim_->get_double_from_d_register(regnum);
92bool PPCDebugger::GetValue(
const char* desc, intptr_t* value) {
95 *value = GetRegisterValue(regnum);
98 if (strncmp(desc,
"0x", 2) == 0) {
100 reinterpret_cast<uintptr_t*
>(value)) == 1;
102 return SScanF(desc,
"%" V8PRIuPTR,
reinterpret_cast<uintptr_t*
>(value)) == 1;
105bool PPCDebugger::GetFPDoubleValue(
const char* desc,
double* value) {
108 *value = sim_->get_double_from_d_register(regnum);
114bool PPCDebugger::SetBreakpoint(Instruction* break_pc) {
116 if (sim_->break_pc_ !=
nullptr) {
121 sim_->break_pc_ = break_pc;
122 sim_->break_instr_ = break_pc->InstructionBits();
131void SetInstructionBitsInCodeSpace(Instruction*
instr,
Instr value,
133 CodePageMemoryModificationScopeForDebugging scope(
139void PPCDebugger::DeleteBreakpoint() {
141 sim_->break_pc_ =
nullptr;
142 sim_->break_instr_ = 0;
145void PPCDebugger::UndoBreakpoint() {
146 if (sim_->break_pc_ !=
nullptr) {
147 SetInstructionBitsInCodeSpace(sim_->break_pc_, sim_->break_instr_,
148 sim_->isolate_->heap());
152void PPCDebugger::RedoBreakpoint() {
153 if (sim_->break_pc_ !=
nullptr) {
154 SetInstructionBitsInCodeSpace(sim_->break_pc_, kBreakpointInstr,
155 sim_->isolate_->heap());
159void PPCDebugger::Debug() {
160 if (
v8_flags.correctness_fuzzer_suppressions) {
161 PrintF(
"Debugger disabled for differential fuzzing.\n");
164 intptr_t last_pc = -1;
167#define COMMAND_SIZE 63
171#define XSTR(a) STR(a)
173 char cmd[COMMAND_SIZE + 1];
174 char arg1[ARG_SIZE + 1];
175 char arg2[ARG_SIZE + 1];
176 char* argv[3] = {cmd, arg1, arg2};
179 cmd[COMMAND_SIZE] = 0;
190 while (!done && !sim_->has_bad_pc()) {
191 if (last_pc != sim_->get_pc()) {
196 dasm.InstructionDecode(buffer,
197 reinterpret_cast<uint8_t*
>(sim_->get_pc()));
199 last_pc = sim_->get_pc();
202 if (line ==
nullptr) {
205 char* last_input = sim_->last_debugger_input();
206 if (strcmp(line,
"\n") == 0 && last_input !=
nullptr) {
210 sim_->set_last_debugger_input(line);
214 int argc = SScanF(line,
215 "%" XSTR(COMMAND_SIZE)
"s "
216 "%" XSTR(ARG_SIZE)
"s "
217 "%" XSTR(ARG_SIZE)
"s",
219 if ((strcmp(cmd,
"si") == 0) || (strcmp(cmd,
"stepi") == 0)) {
223 if ((
reinterpret_cast<Instruction*
>(sim_->get_pc()))
224 ->InstructionBits() == 0x7D821008) {
227 sim_->ExecuteInstruction(
228 reinterpret_cast<Instruction*
>(sim_->get_pc()));
231 if (argc == 2 && last_pc != sim_->get_pc() && GetValue(arg1, &value)) {
237 dasm.InstructionDecode(buffer,
238 reinterpret_cast<uint8_t*
>(sim_->get_pc()));
241 sim_->ExecuteInstruction(
242 reinterpret_cast<Instruction*
>(sim_->get_pc()));
245 }
else if ((strcmp(cmd,
"c") == 0) || (strcmp(cmd,
"cont") == 0)) {
247 if ((
reinterpret_cast<Instruction*
>(sim_->get_pc()))
248 ->InstructionBits() == 0x7D821008) {
252 sim_->ExecuteInstruction(
253 reinterpret_cast<Instruction*
>(sim_->get_pc()));
257 }
else if ((strcmp(cmd,
"p") == 0) || (strcmp(cmd,
"print") == 0)) {
258 if (argc == 2 || (argc == 3 && strcmp(arg2,
"fp") == 0)) {
261 if (strcmp(arg1,
"all") == 0) {
263 value = GetRegisterValue(
i);
266 if ((argc == 3 && strcmp(arg2,
"fp") == 0) &&
i < 8 &&
268 dvalue = GetRegisterPairDoubleValue(
i);
269 PrintF(
" (%f)\n", dvalue);
270 }
else if (
i != 0 && !((
i + 1) & 3)) {
276 "ctr: %08" V8PRIxPTR " xer: %08x cr: %08x\n",
277 sim_->special_reg_pc_, sim_->special_reg_lr_,
278 sim_->special_reg_ctr_, sim_->special_reg_xer_,
279 sim_->condition_reg_);
280 }
else if (strcmp(arg1,
"alld") == 0) {
282 value = GetRegisterValue(
i);
285 if ((argc == 3 && strcmp(arg2,
"fp") == 0) &&
i < 8 &&
287 dvalue = GetRegisterPairDoubleValue(
i);
288 PrintF(
" (%f)\n", dvalue);
289 }
else if (!((
i + 1) % 2)) {
295 "ctr: %08" V8PRIxPTR " xer: %08x cr: %08x\n",
296 sim_->special_reg_pc_, sim_->special_reg_lr_,
297 sim_->special_reg_ctr_, sim_->special_reg_xer_,
298 sim_->condition_reg_);
299 }
else if (strcmp(arg1,
"allf") == 0) {
301 dvalue = GetFPDoubleRegisterValue(
i);
303 PrintF(
"%3s: %f 0x%08x %08x\n",
305 static_cast<uint32_t
>(as_words >> 32),
306 static_cast<uint32_t
>(as_words & 0xFFFFFFFF));
308 }
else if (arg1[0] ==
'r' &&
309 (arg1[1] >=
'0' && arg1[1] <=
'9' &&
310 (arg1[2] ==
'\0' || (arg1[2] >=
'0' && arg1[2] <=
'9' &&
311 arg1[3] ==
'\0')))) {
312 int regnum = strtoul(&arg1[1], 0, 10);
314 value = GetRegisterValue(regnum);
318 PrintF(
"%s unrecognized\n", arg1);
321 if (GetValue(arg1, &value)) {
324 }
else if (GetFPDoubleValue(arg1, &dvalue)) {
326 PrintF(
"%s: %f 0x%08x %08x\n", arg1, dvalue,
327 static_cast<uint32_t
>(as_words >> 32),
328 static_cast<uint32_t
>(as_words & 0xFFFFFFFF));
330 PrintF(
"%s unrecognized\n", arg1);
334 PrintF(
"print <register>\n");
336 }
else if ((strcmp(cmd,
"po") == 0) ||
337 (strcmp(cmd,
"printobject") == 0)) {
341 if (GetValue(arg1, &value)) {
343 os << arg1 <<
": \n";
348 os << Brief(obj) <<
"\n";
351 os << arg1 <<
" unrecognized\n";
354 PrintF(
"printobject <value>\n");
356 }
else if (strcmp(cmd,
"setpc") == 0) {
359 if (!GetValue(arg1, &value)) {
360 PrintF(
"%s unrecognized\n", arg1);
364 }
else if (strcmp(cmd,
"stack") == 0 || strcmp(cmd,
"mem") == 0 ||
365 strcmp(cmd,
"dump") == 0) {
366 intptr_t* cur =
nullptr;
367 intptr_t*
end =
nullptr;
370 if (strcmp(cmd,
"stack") == 0) {
371 cur =
reinterpret_cast<intptr_t*
>(sim_->get_register(Simulator::sp));
374 if (!GetValue(arg1, &value)) {
375 PrintF(
"%s unrecognized\n", arg1);
378 cur =
reinterpret_cast<intptr_t*
>(
value);
383 if (argc == next_arg) {
386 if (!GetValue(argv[next_arg], &words)) {
392 bool skip_obj_print = (strcmp(cmd,
"dump") == 0);
395 reinterpret_cast<intptr_t
>(cur), *cur, *cur);
397 Heap* current_heap = sim_->isolate_->heap();
398 if (!skip_obj_print) {
413 }
else if (strcmp(cmd,
"disasm") == 0 || strcmp(cmd,
"di") == 0) {
419 uint8_t* prev =
nullptr;
420 uint8_t* cur =
nullptr;
421 uint8_t*
end =
nullptr;
424 cur =
reinterpret_cast<uint8_t*
>(sim_->get_pc());
426 }
else if (argc == 2) {
428 if (regnum !=
kNoRegister || strncmp(arg1,
"0x", 2) == 0) {
431 if (GetValue(arg1, &value)) {
432 cur =
reinterpret_cast<uint8_t*
>(
value);
439 if (GetValue(arg1, &value)) {
440 cur =
reinterpret_cast<uint8_t*
>(sim_->get_pc());
448 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
449 cur =
reinterpret_cast<uint8_t*
>(value1);
456 cur += dasm.InstructionDecode(buffer, cur);
460 }
else if (strcmp(cmd,
"gdb") == 0) {
461 PrintF(
"relinquishing control to gdb\n");
463 PrintF(
"regaining control from gdb\n");
464 }
else if (strcmp(cmd,
"break") == 0) {
467 if (GetValue(arg1, &value)) {
468 if (!SetBreakpoint(
reinterpret_cast<Instruction*
>(value))) {
469 PrintF(
"setting breakpoint failed\n");
472 PrintF(
"%s unrecognized\n", arg1);
475 PrintF(
"break <address>\n");
477 }
else if (strcmp(cmd,
"del") == 0) {
479 }
else if (strcmp(cmd,
"cr") == 0) {
480 PrintF(
"Condition reg: %08x\n", sim_->condition_reg_);
481 }
else if (strcmp(cmd,
"lr") == 0) {
483 }
else if (strcmp(cmd,
"ctr") == 0) {
485 }
else if (strcmp(cmd,
"xer") == 0) {
486 PrintF(
"XER: %08x\n", sim_->special_reg_xer_);
487 }
else if (strcmp(cmd,
"fpscr") == 0) {
488 PrintF(
"FPSCR: %08x\n", sim_->fp_condition_reg_);
489 }
else if (strcmp(cmd,
"stop") == 0) {
492 Instruction* stop_instr =
reinterpret_cast<Instruction*
>(stop_pc);
493 Instruction* msg_address =
494 reinterpret_cast<Instruction*
>(stop_pc +
kInstrSize);
495 if ((argc == 2) && (strcmp(arg1,
"unstop") == 0)) {
497 if (sim_->isStopInstruction(stop_instr)) {
498 SetInstructionBitsInCodeSpace(stop_instr, kNopInstr,
499 sim_->isolate_->heap());
500 msg_address->SetInstructionBits(kNopInstr);
502 PrintF(
"Not at debugger stop.\n");
504 }
else if (argc == 3) {
506 if (strcmp(arg1,
"info") == 0) {
507 if (strcmp(arg2,
"all") == 0) {
508 PrintF(
"Stop information:\n");
509 for (uint32_t
i = 0;
i < sim_->kNumOfWatchedStops;
i++) {
510 sim_->PrintStopInfo(
i);
512 }
else if (GetValue(arg2, &value)) {
513 sim_->PrintStopInfo(value);
515 PrintF(
"Unrecognized argument.\n");
517 }
else if (strcmp(arg1,
"enable") == 0) {
519 if (strcmp(arg2,
"all") == 0) {
520 for (uint32_t
i = 0;
i < sim_->kNumOfWatchedStops;
i++) {
523 }
else if (GetValue(arg2, &value)) {
524 sim_->EnableStop(value);
526 PrintF(
"Unrecognized argument.\n");
528 }
else if (strcmp(arg1,
"disable") == 0) {
530 if (strcmp(arg2,
"all") == 0) {
531 for (uint32_t
i = 0;
i < sim_->kNumOfWatchedStops;
i++) {
532 sim_->DisableStop(
i);
534 }
else if (GetValue(arg2, &value)) {
535 sim_->DisableStop(value);
537 PrintF(
"Unrecognized argument.\n");
541 PrintF(
"Wrong usage. Use help command for more information.\n");
543 }
else if ((strcmp(cmd,
"t") == 0) || strcmp(cmd,
"trace") == 0) {
544 sim_->ToggleInstructionTracing();
545 PrintF(
"Trace of executed instructions is %s\n",
546 sim_->InstructionTracingEnabled() ?
"on" :
"off");
547 }
else if ((strcmp(cmd,
"h") == 0) || (strcmp(cmd,
"help") == 0)) {
549 PrintF(
" continue execution (alias 'c')\n");
550 PrintF(
"stepi [num instructions]\n");
551 PrintF(
" step one/num instruction(s) (alias 'si')\n");
552 PrintF(
"print <register>\n");
553 PrintF(
" print register content (alias 'p')\n");
554 PrintF(
" use register name 'all' to display all integer registers\n");
556 " use register name 'alld' to display integer registers "
557 "with decimal values\n");
558 PrintF(
" use register name 'rN' to display register number 'N'\n");
559 PrintF(
" add argument 'fp' to print register pair double values\n");
561 " use register name 'allf' to display floating-point "
563 PrintF(
"printobject <register>\n");
564 PrintF(
" print an object from a register (alias 'po')\n");
566 PrintF(
" print condition register\n");
568 PrintF(
" print link register\n");
570 PrintF(
" print ctr register\n");
575 PrintF(
"stack [<num words>]\n");
576 PrintF(
" dump stack content, default dump 10 words)\n");
577 PrintF(
"mem <address> [<num words>]\n");
578 PrintF(
" dump memory content, default dump 10 words)\n");
579 PrintF(
"dump [<words>]\n");
581 " dump memory content without pretty printing JS objects, default "
583 PrintF(
"disasm [<instructions>]\n");
584 PrintF(
"disasm [<address/register>]\n");
585 PrintF(
"disasm [[<address/register>] <instructions>]\n");
586 PrintF(
" disassemble code, default is 10 instructions\n");
587 PrintF(
" from pc (alias 'di')\n");
590 PrintF(
"break <address>\n");
591 PrintF(
" set a break point on the address\n");
593 PrintF(
" delete the breakpoint\n");
594 PrintF(
"trace (alias 't')\n");
595 PrintF(
" toogle the tracing of all executed statements\n");
596 PrintF(
"stop feature:\n");
597 PrintF(
" Description:\n");
598 PrintF(
" Stops are debug instructions inserted by\n");
599 PrintF(
" the Assembler::stop() function.\n");
600 PrintF(
" When hitting a stop, the Simulator will\n");
601 PrintF(
" stop and give control to the PPCDebugger.\n");
602 PrintF(
" The first %d stop codes are watched:\n",
603 Simulator::kNumOfWatchedStops);
604 PrintF(
" - They can be enabled / disabled: the Simulator\n");
605 PrintF(
" will / won't stop when hitting them.\n");
606 PrintF(
" - The Simulator keeps track of how many times they \n");
607 PrintF(
" are met. (See the info command.) Going over a\n");
608 PrintF(
" disabled stop still increases its counter. \n");
610 PrintF(
" stop info all/<code> : print infos about number <code>\n");
611 PrintF(
" or all stop(s).\n");
612 PrintF(
" stop enable/disable all/<code> : enables / disables\n");
613 PrintF(
" all or number <code> stop(s)\n");
615 PrintF(
" ignore the stop instruction at the current location\n");
618 PrintF(
"Unknown command: %s\n", cmd);
636bool Simulator::InstructionTracingEnabled() {
return instruction_tracing_; }
638void Simulator::ToggleInstructionTracing() {
639 instruction_tracing_ = !instruction_tracing_;
642bool Simulator::ICacheMatch(
void*
one,
void* two) {
643 DCHECK_EQ(
reinterpret_cast<intptr_t
>(
one) & CachePage::kPageMask, 0);
644 DCHECK_EQ(
reinterpret_cast<intptr_t
>(two) & CachePage::kPageMask, 0);
648static uint32_t ICacheHash(
void*
key) {
649 return static_cast<uint32_t
>(
reinterpret_cast<uintptr_t
>(
key)) >> 2;
652static bool AllOnOnePage(uintptr_t
start,
int size) {
653 intptr_t start_page = (
start & ~CachePage::kPageMask);
654 intptr_t end_page = ((
start +
size) & ~CachePage::kPageMask);
655 return start_page == end_page;
658static bool is_snan(
float input) {
659 uint32_t kQuietNanFPBit = 1 << 22;
661 return isnan(input) && ((InputAsUint & kQuietNanFPBit) == 0);
664static bool is_snan(
double input) {
665 uint64_t kQuietNanDPBit = 1L << 51;
667 return isnan(input) && ((InputAsUint & kQuietNanDPBit) == 0);
670void Simulator::set_last_debugger_input(
char* input) {
672 last_debugger_input_ = input;
675void Simulator::SetRedirectInstruction(Instruction* instruction) {
680 void* start_addr,
size_t size) {
681 intptr_t
start =
reinterpret_cast<intptr_t
>(start_addr);
682 int intra_line = (
start & CachePage::kLineMask);
685 size = ((size - 1) | CachePage::kLineMask) + 1;
687 while (!AllOnOnePage(
start, size - 1)) {
688 int bytes_to_flush = CachePage::kPageSize -
offset;
689 FlushOnePage(i_cache,
start, bytes_to_flush);
690 start += bytes_to_flush;
691 size -= bytes_to_flush;
696 FlushOnePage(i_cache,
start, size);
703 if (entry->value ==
nullptr) {
704 CachePage* new_page =
new CachePage();
705 entry->value = new_page;
707 return reinterpret_cast<CachePage*
>(entry->value);
712 intptr_t
start,
int size) {
716 DCHECK_EQ(size & CachePage::kLineMask, 0);
717 void* page =
reinterpret_cast<void*
>(
start & (~CachePage::kPageMask));
719 CachePage* cache_page = GetCachePage(i_cache, page);
720 char* valid_bytemap = cache_page->ValidityByte(
offset);
721 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
725 Instruction*
instr) {
726 intptr_t address =
reinterpret_cast<intptr_t
>(
instr);
727 void* page =
reinterpret_cast<void*
>(address & (~CachePage::kPageMask));
728 void* line =
reinterpret_cast<void*
>(address & (~CachePage::kLineMask));
729 int offset = (address & CachePage::kPageMask);
730 CachePage* cache_page = GetCachePage(i_cache, page);
731 char* cache_valid_byte = cache_page->ValidityByte(
offset);
732 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
733 char* cached_line = cache_page->CachedData(
offset & ~CachePage::kLineMask);
740 memcpy(cached_line, line, CachePage::kLineLength);
741 *cache_valid_byte = CachePage::LINE_VALID;
745Simulator::Simulator(Isolate* isolate) :
isolate_(isolate) {
748 stack_ =
reinterpret_cast<uint8_t*
>(base::Malloc(AllocatedStackSize()));
749 pc_modified_ =
false;
756 for (
int i = 0;
i < kNumGPRs;
i++) {
760 fp_condition_reg_ = 0;
763 special_reg_ctr_ = 0;
766 for (
int i = 0;
i < kNumFPRs;
i++) {
767 fp_registers_[
i] = 0.0;
775 last_debugger_input_ =
nullptr;
778 SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);
781Simulator::~Simulator() { base::Free(stack_); }
784Simulator* Simulator::current(Isolate* isolate) {
786 isolate->FindOrAllocatePerThreadDataForThisThread();
789 Simulator* sim = isolate_data->simulator();
790 if (sim ==
nullptr) {
792 sim =
new Simulator(isolate);
793 isolate_data->set_simulator(sim);
799void Simulator::set_register(
int reg, intptr_t value) {
805intptr_t Simulator::get_register(
int reg)
const {
809 if (
reg >= kNumGPRs)
return 0;
814double Simulator::get_double_from_register_pair(
int reg) {
822void Simulator::set_pc(intptr_t value) {
824 special_reg_pc_ =
value;
827bool Simulator::has_bad_pc()
const {
828 return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc));
832intptr_t Simulator::get_pc()
const {
return special_reg_pc_; }
835intptr_t Simulator::get_lr()
const {
return special_reg_lr_; }
841void Simulator::GetFpArgs(
double*
x,
double*
y, intptr_t*
z) {
842 *
x = get_double_from_d_register(1);
843 *
y = get_double_from_d_register(2);
844 *
z = get_register(3);
848void Simulator::SetFpResult(
const double&
result) {
849 set_d_register_from_double(1,
result);
852void Simulator::TrashCallerSaveRegisters() {
861#define GENERATE_RW_FUNC(size, type) \
862 type Simulator::Read##size(uintptr_t addr) { \
864 Read(addr, &value); \
867 type Simulator::ReadEx##size(uintptr_t addr) { \
869 ReadEx(addr, &value); \
872 void Simulator::Write##size(uintptr_t addr, type value) { \
873 Write(addr, value); \
875 int32_t Simulator::WriteEx##size(uintptr_t addr, type value) { \
876 return WriteEx(addr, value); \
879RW_VAR_LIST(GENERATE_RW_FUNC)
880#undef GENERATE_RW_FUNC
883uintptr_t Simulator::StackLimit(uintptr_t c_limit)
const {
886 if (base::Stack::GetCurrentStackPosition() < c_limit) {
887 return reinterpret_cast<uintptr_t
>(get_sp());
892 return reinterpret_cast<uintptr_t
>(stack_) + kStackProtectionSize;
895uintptr_t Simulator::StackBase()
const {
896 return reinterpret_cast<uintptr_t
>(stack_) + UsableStackSize();
899base::Vector<uint8_t> Simulator::GetCentralStackView()
const {
903 return base::VectorOf(stack_, UsableStackSize());
907 for (
int i = 0;
i < kNumGPRs; ++
i) {
908 visitor->
VisitPointer(
reinterpret_cast<const void*
>(get_register(
i)));
911 for (
const void*
const* current =
912 reinterpret_cast<const void* const*
>(get_sp());
914 const void* address = *
current;
915 if (address ==
nullptr) {
923void Simulator::Format(Instruction*
instr,
const char* format) {
924 PrintF(
"Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR ": %s\n",
925 reinterpret_cast<intptr_t
>(
instr), format);
930bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
931 uint32_t uleft =
static_cast<uint32_t
>(left);
932 uint32_t uright =
static_cast<uint32_t
>(right);
933 uint32_t urest = 0xFFFFFFFFU - uleft;
935 return (uright > urest) ||
936 (
carry && (((uright + 1) > urest) || (uright > (urest - 1))));
940bool Simulator::BorrowFrom(int32_t left, int32_t right) {
941 uint32_t uleft =
static_cast<uint32_t
>(left);
942 uint32_t uright =
static_cast<uint32_t
>(right);
944 return (uright > uleft);
948bool Simulator::OverflowFrom(int32_t alu_out, int32_t left, int32_t right,
953 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
955 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
958 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
960 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
965static void decodeObjectPair(ObjectPair* pair, intptr_t*
x, intptr_t*
y) {
966 *
x =
static_cast<intptr_t
>(pair->x);
967 *
y =
static_cast<intptr_t
>(pair->y);
971using SimulatorRuntimeCall = intptr_t (*)(
972 intptr_t arg0, intptr_t arg1, intptr_t arg2, intptr_t arg3, intptr_t arg4,
973 intptr_t arg5, intptr_t arg6, intptr_t arg7, intptr_t arg8, intptr_t arg9,
974 intptr_t arg10, intptr_t arg11, intptr_t arg12, intptr_t arg13,
975 intptr_t arg14, intptr_t arg15, intptr_t arg16, intptr_t arg17,
976 intptr_t arg18, intptr_t arg19);
977using SimulatorRuntimePairCall =
ObjectPair (*)(
978 intptr_t arg0, intptr_t arg1, intptr_t arg2, intptr_t arg3, intptr_t arg4,
979 intptr_t arg5, intptr_t arg6, intptr_t arg7, intptr_t arg8, intptr_t arg9,
980 intptr_t arg10, intptr_t arg11, intptr_t arg12, intptr_t arg13,
981 intptr_t arg14, intptr_t arg15, intptr_t arg16, intptr_t arg17,
982 intptr_t arg18, intptr_t arg19);
985using SimulatorRuntimeCompareCall = int (*)(
double darg0,
double darg1);
986using SimulatorRuntimeFPFPCall = double (*)(
double darg0,
double darg1);
987using SimulatorRuntimeFPCall = double (*)(
double darg0);
988using SimulatorRuntimeFPIntCall = double (*)(
double darg0, intptr_t arg0);
989using SimulatorRuntimeIntFPCall =
int32_t (*)(
double darg0);
992using SimulatorRuntimeFPTaggedCall = double (*)(
int32_t arg0,
int32_t arg1,
997using SimulatorRuntimeDirectApiCall = void (*)(intptr_t arg0);
1000using SimulatorRuntimeDirectGetterCall = void (*)(intptr_t arg0, intptr_t arg1);
1004void Simulator::SoftwareInterrupt(Instruction*
instr) {
1005 int svc =
instr->SvcValue();
1010 bool stack_aligned =
1011 (get_register(sp) & (
v8_flags.sim_stack_alignment - 1)) == 0;
1012 Redirection* redirection = Redirection::FromInstruction(
instr);
1013 const int kArgCount = 20;
1014 const int kRegisterArgCount = 8;
1015 int arg0_regnum = 3;
1016 intptr_t result_buffer = 0;
1017 bool uses_result_buffer =
1018 (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR &&
1020 if (uses_result_buffer) {
1021 result_buffer = get_register(r3);
1024 intptr_t arg[kArgCount];
1026 for (
int i = 0;
i < kRegisterArgCount;
i++) {
1027 arg[
i] = get_register(arg0_regnum +
i);
1029 intptr_t* stack_pointer =
reinterpret_cast<intptr_t*
>(get_register(sp));
1031 for (
int i = kRegisterArgCount, j = 0;
i < kArgCount;
i++, j++) {
1034 static_assert(kArgCount == kRegisterArgCount + 12);
1035 static_assert(kMaxCParameters == kArgCount);
1037 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1038 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1039 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1040 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL) ||
1041 (redirection->type() == ExternalReference::BUILTIN_INT_FP_CALL);
1044 intptr_t saved_lr = special_reg_lr_;
1046 reinterpret_cast<intptr_t
>(redirection->external_function());
1048 double dval0, dval1;
1052 GetFpArgs(&dval0, &dval1, &ival);
1053 if (InstructionTracingEnabled() || !stack_aligned) {
1054 SimulatorRuntimeCall generic_target =
1055 reinterpret_cast<SimulatorRuntimeCall
>(external);
1056 switch (redirection->type()) {
1057 case ExternalReference::BUILTIN_FP_FP_CALL:
1058 case ExternalReference::BUILTIN_COMPARE_CALL:
1059 PrintF(
"Call to host function at %p with args %f, %f",
1063 case ExternalReference::BUILTIN_FP_CALL:
1064 PrintF(
"Call to host function at %p with arg %f",
1068 case ExternalReference::BUILTIN_FP_INT_CALL:
1073 case ExternalReference::BUILTIN_INT_FP_CALL:
1074 PrintF(
"Call to host function at %p with args %f",
1081 if (!stack_aligned) {
1087 CHECK(stack_aligned);
1088 switch (redirection->type()) {
1089 case ExternalReference::BUILTIN_COMPARE_CALL: {
1090 SimulatorRuntimeCompareCall target =
1091 reinterpret_cast<SimulatorRuntimeCompareCall
>(external);
1092 iresult =
target(dval0, dval1);
1093 set_register(r3, iresult);
1096 case ExternalReference::BUILTIN_FP_FP_CALL: {
1097 SimulatorRuntimeFPFPCall target =
1098 reinterpret_cast<SimulatorRuntimeFPFPCall
>(external);
1099 dresult =
target(dval0, dval1);
1100 SetFpResult(dresult);
1103 case ExternalReference::BUILTIN_FP_CALL: {
1104 SimulatorRuntimeFPCall target =
1105 reinterpret_cast<SimulatorRuntimeFPCall
>(external);
1107 SetFpResult(dresult);
1110 case ExternalReference::BUILTIN_FP_INT_CALL: {
1111 SimulatorRuntimeFPIntCall target =
1112 reinterpret_cast<SimulatorRuntimeFPIntCall
>(external);
1113 dresult =
target(dval0, ival);
1114 SetFpResult(dresult);
1117 case ExternalReference::BUILTIN_INT_FP_CALL: {
1118 SimulatorRuntimeIntFPCall target =
1119 reinterpret_cast<SimulatorRuntimeIntFPCall
>(external);
1122 TrashCallerSaveRegisters();
1124 set_register(r0,
static_cast<int32_t>(iresult));
1130 if (InstructionTracingEnabled()) {
1131 switch (redirection->type()) {
1132 case ExternalReference::BUILTIN_COMPARE_CALL:
1133 case ExternalReference::BUILTIN_INT_FP_CALL:
1134 PrintF(
"Returned %08x\n", iresult);
1136 case ExternalReference::BUILTIN_FP_FP_CALL:
1137 case ExternalReference::BUILTIN_FP_CALL:
1138 case ExternalReference::BUILTIN_FP_INT_CALL:
1139 PrintF(
"Returned %f\n", dresult);
1145 }
else if (redirection->type() ==
1146 ExternalReference::BUILTIN_FP_POINTER_CALL) {
1147 if (InstructionTracingEnabled() || !stack_aligned) {
1149 reinterpret_cast<void*
>(external), arg[0]);
1150 if (!stack_aligned) {
1156 CHECK(stack_aligned);
1157 SimulatorRuntimeFPTaggedCall target =
1158 reinterpret_cast<SimulatorRuntimeFPTaggedCall
>(external);
1159 double dresult =
target(arg[0], arg[1], arg[2], arg[3]);
1161 TrashCallerSaveRegisters();
1163 SetFpResult(dresult);
1164 if (InstructionTracingEnabled()) {
1165 PrintF(
"Returned %f\n", dresult);
1167 }
else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1171 if (InstructionTracingEnabled() || !stack_aligned) {
1173 reinterpret_cast<void*
>(external), arg[0]);
1174 if (!stack_aligned) {
1180 CHECK(stack_aligned);
1181 SimulatorRuntimeDirectApiCall target =
1182 reinterpret_cast<SimulatorRuntimeDirectApiCall
>(external);
1184 }
else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
1188 if (InstructionTracingEnabled() || !stack_aligned) {
1191 reinterpret_cast<void*
>(external), arg[0], arg[1]);
1192 if (!stack_aligned) {
1198 CHECK(stack_aligned);
1199 SimulatorRuntimeDirectGetterCall target =
1200 reinterpret_cast<SimulatorRuntimeDirectGetterCall
>(external);
1202 arg[0] = base::bit_cast<intptr_t>(arg[0]);
1207 if (InstructionTracingEnabled() || !stack_aligned) {
1208 SimulatorRuntimeCall target =
1209 reinterpret_cast<SimulatorRuntimeCall
>(external);
1211 "Call to host function at %p,\n"
1219 reinterpret_cast<void*
>(
FUNCTION_ADDR(target)), arg[0], arg[1],
1220 arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9],
1221 arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16],
1222 arg[17], arg[18], arg[19]);
1223 if (!stack_aligned) {
1229 CHECK(stack_aligned);
1230 if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) {
1231 SimulatorRuntimePairCall target =
1232 reinterpret_cast<SimulatorRuntimePairCall
>(external);
1234 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6],
1235 arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13],
1236 arg[14], arg[15], arg[16], arg[17], arg[18], arg[19]);
1240 if (InstructionTracingEnabled()) {
1244 set_register(r3,
x);
1245 set_register(r4,
y);
1247 memcpy(
reinterpret_cast<void*
>(result_buffer), &
result,
1248 sizeof(ObjectPair));
1249 set_register(r3, result_buffer);
1262 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
1263 redirection->type() == ExternalReference::FAST_C_CALL);
1264 SimulatorRuntimeCall target =
1265 reinterpret_cast<SimulatorRuntimeCall
>(external);
1267 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6],
1268 arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13],
1269 arg[14], arg[15], arg[16], arg[17], arg[18], arg[19]);
1270 if (InstructionTracingEnabled()) {
1273 set_register(r3,
result);
1280 PPCDebugger(
this).Debug();
1284 if (svc >= (1 << 23)) {
1286 if (isWatchedStop(code)) {
1287 IncreaseStopCounter(code);
1291 if (isEnabledStop(code)) {
1292 if (code != kMaxStopCode) {
1293 PrintF(
"Simulator hit stop %u. ", code);
1295 PrintF(
"Simulator hit stop. ");
1299 set_pc(get_pc() + kInstrSize + kSystemPointerSize);
1309bool Simulator::isStopInstruction(Instruction*
instr) {
1310 return (
instr->Bits(27, 24) == 0xF) && (
instr->SvcValue() >= kStopCode);
1313bool Simulator::isWatchedStop(uint32_t code) {
1315 return code < kNumOfWatchedStops;
1318bool Simulator::isEnabledStop(uint32_t code) {
1321 return !isWatchedStop(code) ||
1322 !(watched_stops_[
code].count & kStopDisabledBit);
1325void Simulator::EnableStop(uint32_t code) {
1326 DCHECK(isWatchedStop(code));
1327 if (!isEnabledStop(code)) {
1328 watched_stops_[
code].count &= ~kStopDisabledBit;
1332void Simulator::DisableStop(uint32_t code) {
1333 DCHECK(isWatchedStop(code));
1334 if (isEnabledStop(code)) {
1335 watched_stops_[
code].count |= kStopDisabledBit;
1339void Simulator::IncreaseStopCounter(uint32_t code) {
1341 DCHECK(isWatchedStop(code));
1342 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7FFFFFFF) {
1344 "Stop counter for code %i has overflowed.\n"
1345 "Enabling this code and reseting the counter to 0.\n",
1347 watched_stops_[
code].count = 0;
1350 watched_stops_[
code].count++;
1355void Simulator::PrintStopInfo(uint32_t code) {
1357 if (!isWatchedStop(code)) {
1358 PrintF(
"Stop not watched.");
1360 const char* state = isEnabledStop(code) ?
"Enabled" :
"Disabled";
1361 int32_t count = watched_stops_[
code].count & ~kStopDisabledBit;
1364 if (watched_stops_[code].desc) {
1365 PrintF(
"stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code,
1366 state, count, watched_stops_[code].desc);
1368 PrintF(
"stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state,
1375void Simulator::SetCR0(intptr_t
result,
bool setSO) {
1389 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
1392void Simulator::SetCR6(
bool true_for_all) {
1393 int32_t clear_cr6_mask = 0xFFFFFF0F;
1395 condition_reg_ = (condition_reg_ & clear_cr6_mask) | 0x80;
1397 condition_reg_ = (condition_reg_ & clear_cr6_mask) | 0x20;
1401void Simulator::ExecuteBranchConditional(Instruction*
instr, BCType type) {
1402 int bo =
instr->Bits(25, 21) << 21;
1403 int condition_bit =
instr->Bits(20, 16);
1404 int condition_mask = 0x80000000 >> condition_bit;
1410 if (condition_reg_ & condition_mask)
return;
1417 if (!(condition_reg_ & condition_mask))
return;
1422 special_reg_ctr_ -= 1;
1423 if ((special_reg_ctr_ == 0) != (bo == DCBEZ))
return;
1432 intptr_t old_pc = get_pc();
1441 set_pc(special_reg_lr_);
1444 set_pc(special_reg_ctr_);
1448 if (
instr->Bit(0) == 1) {
1449 special_reg_lr_ = old_pc + 4;
1454#define GET_ADDRESS(a, b, a_val, b_val) \
1455 intptr_t a_val = a == 0 ? 0 : get_register(a); \
1456 intptr_t b_val = get_register(b);
1457#define DECODE_VX_INSTRUCTION(d, a, b, source_or_target) \
1458 int d = instr->R##source_or_target##Value(); \
1459 int a = instr->RAValue(); \
1460 int b = instr->RBValue();
1461#define FOR_EACH_LANE(i, type) \
1462 for (uint32_t i = 0; i < kSimd128Size / sizeof(type); i++)
1463template <
typename A,
typename T,
typename Operation>
1464void VectorCompareOp(Simulator* sim, Instruction*
instr,
bool is_fp,
1466 DECODE_VX_INSTRUCTION(t, a, b, T)
1467 bool true_for_all =
true;
1468 FOR_EACH_LANE(
i, A) {
1469 A a_val = sim->get_simd_register_by_lane<
A>(
a,
i);
1470 A b_val = sim->get_simd_register_by_lane<
A>(b,
i);
1472 bool is_not_nan = is_fp ? !isnan(a_val) && !isnan(b_val) : true;
1473 if (is_not_nan && op(a_val, b_val)) {
1476 true_for_all =
false;
1478 sim->set_simd_register_by_lane<T>(t,
i, t_val);
1480 if (
instr->Bit(10)) {
1481 sim->SetCR6(true_for_all);
1485template <
typename S,
typename T>
1486void VectorConverFromFPSaturate(Simulator* sim, Instruction*
instr, T min_val,
1487 T max_val,
bool even_lane_result =
false) {
1488 int t =
instr->RTValue();
1489 int b =
instr->RBValue();
1490 FOR_EACH_LANE(
i, S) {
1492 double b_val =
static_cast<double>(sim->get_simd_register_by_lane<
S>(b,
i));
1497 b_val = std::trunc(b_val);
1498 if (b_val < min_val) {
1500 }
else if (b_val > max_val) {
1503 t_val =
static_cast<T
>(b_val);
1506 sim->set_simd_register_by_lane<T>(t, even_lane_result ? 2 *
i :
i, t_val);
1510template <
typename S,
typename T>
1511void VectorPackSaturate(Simulator* sim, Instruction*
instr, S min_val,
1513 DECODE_VX_INSTRUCTION(t, a, b, T)
1520 if (count == kSimd128Size /
sizeof(S)) {
1524 value = sim->get_simd_register_by_lane<
S>(src,
count);
1525 if (value > max_val) {
1527 }
else if (value < min_val) {
1530 temps[
i] =
static_cast<T
>(
value);
1532 FOR_EACH_LANE(
i, T) { sim->set_simd_register_by_lane<T>(t,
i, temps[
i]); }
1535template <
typename T>
1536T VSXFPMin(T
x, T
y) {
1539 if (std::isnan(
x) && std::isnan(
y))
return NAN;
1541 if (std::signbit(
x) < std::signbit(
y))
return y;
1542 if (std::signbit(
y) < std::signbit(
x))
return x;
1543 return std::fmin(
x,
y);
1546template <
typename T>
1547T VSXFPMax(T
x, T
y) {
1550 if (std::isnan(
x) && std::isnan(
y))
return NAN;
1552 if (std::signbit(
x) < std::signbit(
y))
return x;
1553 if (std::signbit(
y) < std::signbit(
x))
return y;
1554 return std::fmax(
x,
y);
1557float VMXFPMin(
float x,
float y) {
1559 if (std::isnan(
x) || std::isnan(
y))
return NAN;
1561 if (std::signbit(
x) < std::signbit(
y))
return y;
1562 if (std::signbit(
y) < std::signbit(
x))
return x;
1563 return x <
y ?
x :
y;
1566float VMXFPMax(
float x,
float y) {
1568 if (std::isnan(
x) || std::isnan(
y))
return NAN;
1570 if (std::signbit(
x) < std::signbit(
y))
return x;
1571 if (std::signbit(
y) < std::signbit(
x))
return y;
1572 return x >
y ?
x :
y;
1575void Simulator::ExecuteGeneric(Instruction*
instr) {
1576 uint32_t opcode =
instr->OpcodeBase();
1579 case PLOAD_STORE_8LS:
1580 case PLOAD_STORE_MLS: {
1585 uint64_t prefix_value =
instr->Bits(17, 0);
1587 Instruction* next_instr =
1588 reinterpret_cast<Instruction*
>(get_pc() +
kInstrSize);
1589 uint16_t suffix_value = next_instr->Bits(15, 0);
1590 int64_t im_val =
SIGN_EXT_IMM34((prefix_value << 16) | suffix_value);
1591 switch (next_instr->OpcodeBase()) {
1594 int rt = next_instr->RTValue();
1595 int ra = next_instr->RAValue();
1600 intptr_t ra_val = get_register(ra);
1601 alu_out = ra_val + im_val;
1603 set_register(rt, alu_out);
1608 int ra = next_instr->RAValue();
1609 int rt = next_instr->RTValue();
1610 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1611 set_register(rt, ReadB(ra_val + im_val) & 0xFF);
1616 int ra = next_instr->RAValue();
1617 int rt = next_instr->RTValue();
1618 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1619 uintptr_t
result = ReadHU(ra_val + im_val) & 0xFFFF;
1620 set_register(rt,
result);
1625 int ra = next_instr->RAValue();
1626 int rt = next_instr->RTValue();
1627 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1628 intptr_t
result = ReadH(ra_val + im_val);
1629 set_register(rt,
result);
1634 int ra = next_instr->RAValue();
1635 int rt = next_instr->RTValue();
1636 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1637 set_register(rt, ReadWU(ra_val + im_val));
1642 int ra = next_instr->RAValue();
1643 int rt = next_instr->RTValue();
1644 int64_t ra_val = ra == 0 ? 0 : get_register(ra);
1645 set_register(rt, ReadW(ra_val + im_val));
1650 int ra = next_instr->RAValue();
1651 int rt = next_instr->RTValue();
1652 int64_t ra_val = ra == 0 ? 0 : get_register(ra);
1653 set_register(rt, ReadDW(ra_val + im_val));
1658 int frt = next_instr->RTValue();
1659 int ra = next_instr->RAValue();
1660 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1661 int32_t val = ReadW(ra_val + im_val);
1662 float* fptr =
reinterpret_cast<float*
>(&val);
1663#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
1665 if ((val & 0x7F800000) == 0x7F800000) {
1666 int64_t dval =
static_cast<int64_t
>(val);
1667 dval = ((dval & 0xC0000000) << 32) | ((dval & 0x40000000) << 31) |
1668 ((dval & 0x40000000) << 30) | ((dval & 0x7FFFFFFF) << 29) |
1670 set_d_register(frt, dval);
1672 set_d_register_from_double(frt,
static_cast<double>(*fptr));
1675 set_d_register_from_double(frt,
static_cast<double>(*fptr));
1681 int frt = next_instr->RTValue();
1682 int ra = next_instr->RAValue();
1683 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1684 int64_t dptr = ReadDW(ra_val + im_val);
1685 set_d_register(frt, dptr);
1690 int ra = next_instr->RAValue();
1691 int rs = next_instr->RSValue();
1692 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1693 WriteB(ra_val + im_val, get_register(rs));
1698 int ra = next_instr->RAValue();
1699 int rs = next_instr->RSValue();
1700 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1701 WriteH(ra_val + im_val, get_register(rs));
1706 int ra = next_instr->RAValue();
1707 int rs = next_instr->RSValue();
1708 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1709 WriteW(ra_val + im_val, get_register(rs));
1714 int ra = next_instr->RAValue();
1715 int rs = next_instr->RSValue();
1716 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1717 WriteDW(ra_val + im_val, get_register(rs));
1722 int frs = next_instr->RSValue();
1723 int ra = next_instr->RAValue();
1724 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1725 float frs_val =
static_cast<float>(get_double_from_d_register(frs));
1727#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
1730 int64_t dval = get_d_register(frs);
1731 if ((dval & 0x7FF0000000000000) == 0x7FF0000000000000) {
1732 sval = ((dval & 0xC000000000000000) >> 32) |
1733 ((dval & 0x07FFFFFFE0000000) >> 29);
1736 p =
reinterpret_cast<int32_t*
>(&frs_val);
1739 p =
reinterpret_cast<int32_t*
>(&frs_val);
1741 WriteW(ra_val + im_val, *p);
1746 int frs = next_instr->RSValue();
1747 int ra = next_instr->RAValue();
1748 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
1749 int64_t frs_val = get_d_register(frs);
1750 WriteDW(ra_val + im_val, frs_val);
1757 set_pc(get_pc() + (2 * kInstrSize));
1761 int rt =
instr->RTValue();
1762 int ra =
instr->RAValue();
1763 intptr_t ra_val = get_register(ra);
1766 intptr_t alu_out = im_val - ra_val;
1767 set_register(rt, alu_out);
1772 int ra =
instr->RAValue();
1773 uint32_t im_val =
instr->Bits(15, 0);
1774 int cr =
instr->Bits(25, 23);
1778 uintptr_t ra_val = get_register(ra);
1779 if (ra_val < im_val) {
1782 if (ra_val > im_val) {
1785 if (ra_val == im_val) {
1789 uint32_t ra_val = get_register(ra);
1790 if (ra_val < im_val) {
1793 if (ra_val > im_val) {
1796 if (ra_val == im_val) {
1800 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
1802 condition_reg_ = (condition_reg_ & ~condition_mask) |
condition;
1806 int ra =
instr->RAValue();
1809 int cr =
instr->Bits(25, 23);
1813 intptr_t ra_val = get_register(ra);
1814 if (ra_val < im_val) {
1817 if (ra_val > im_val) {
1820 if (ra_val == im_val) {
1824 int32_t ra_val = get_register(ra);
1825 if (ra_val < im_val) {
1828 if (ra_val > im_val) {
1831 if (ra_val == im_val) {
1835 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
1837 condition_reg_ = (condition_reg_ & ~condition_mask) |
condition;
1841 int rt =
instr->RTValue();
1842 int ra =
instr->RAValue();
1843 uintptr_t ra_val = get_register(ra);
1845 uintptr_t alu_out = ra_val + im_val;
1847 if (~ra_val < im_val) {
1848 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
1850 special_reg_xer_ &= ~0xF0000000;
1852 set_register(rt, alu_out);
1856 int rt =
instr->RTValue();
1857 int ra =
instr->RAValue();
1863 intptr_t ra_val = get_register(ra);
1864 alu_out = ra_val + im_val;
1866 set_register(rt, alu_out);
1871 int rt =
instr->RTValue();
1872 int ra =
instr->RAValue();
1878 intptr_t ra_val = get_register(ra);
1879 alu_out = ra_val + im_val;
1881 set_register(rt, alu_out);
1885 ExecuteBranchConditional(
instr, BC_OFFSET);
1890 if (
instr->Bit(0) == 1) {
1891 special_reg_lr_ = get_pc() + 4;
1893 set_pc(get_pc() +
offset);
1900 ExecuteBranchConditional(
instr, BC_LINK_REG);
1903 ExecuteBranchConditional(
instr, BC_CTR_REG);
1914 int bt =
instr->Bits(25, 21);
1915 int ba =
instr->Bits(20, 16);
1916 int bb =
instr->Bits(15, 11);
1917 int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
1918 int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
1919 int bt_val = ba_val ^ bb_val;
1920 bt_val = bt_val << (31 - bt);
1921 condition_reg_ &= ~(0x80000000 >> bt);
1922 condition_reg_ |= bt_val;
1926 int bt =
instr->Bits(25, 21);
1927 int ba =
instr->Bits(20, 16);
1928 int bb =
instr->Bits(15, 11);
1929 int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
1930 int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
1931 int bt_val = 1 - (ba_val ^ bb_val);
1932 bt_val = bt_val << (31 - bt);
1933 condition_reg_ &= ~(0x80000000 >> bt);
1934 condition_reg_ |= bt_val;
1944 int ra =
instr->RAValue();
1945 int rs =
instr->RSValue();
1946 uint32_t rs_val = get_register(rs);
1947 int32_t ra_val = get_register(ra);
1948 int sh =
instr->Bits(15, 11);
1949 int mb =
instr->Bits(10, 6);
1950 int me =
instr->Bits(5, 1);
1951 uint32_t
result = base::bits::RotateLeft32(rs_val, sh);
1954 int bit = 0x80000000 >> mb;
1955 for (; mb <= me; mb++) {
1959 }
else if (mb == me + 1) {
1962 int bit = 0x80000000 >> (me + 1);
1964 for (; me < mb; me++) {
1972 set_register(ra,
result);
1973 if (
instr->Bit(0)) {
1980 int ra =
instr->RAValue();
1981 int rs =
instr->RSValue();
1982 uint32_t rs_val = get_register(rs);
1984 if (opcode == RLWINMX) {
1985 sh =
instr->Bits(15, 11);
1987 int rb =
instr->RBValue();
1988 uint32_t rb_val = get_register(rb);
1989 sh = (rb_val & 0x1F);
1991 int mb =
instr->Bits(10, 6);
1992 int me =
instr->Bits(5, 1);
1993 uint32_t
result = base::bits::RotateLeft32(rs_val, sh);
1996 int bit = 0x80000000 >> mb;
1997 for (; mb <= me; mb++) {
2001 }
else if (mb == me + 1) {
2004 int bit = 0x80000000 >> (me + 1);
2006 for (; me < mb; me++) {
2012 set_register(ra,
result);
2013 if (
instr->Bit(0)) {
2019 int rs =
instr->RSValue();
2020 int ra =
instr->RAValue();
2021 intptr_t rs_val = get_register(rs);
2022 uint32_t im_val =
instr->Bits(15, 0);
2023 intptr_t alu_out = rs_val | im_val;
2024 set_register(ra, alu_out);
2028 int rs =
instr->RSValue();
2029 int ra =
instr->RAValue();
2030 intptr_t rs_val = get_register(rs);
2031 uint32_t im_val =
instr->Bits(15, 0);
2032 intptr_t alu_out = rs_val | (im_val << 16);
2033 set_register(ra, alu_out);
2037 int rs =
instr->RSValue();
2038 int ra =
instr->RAValue();
2039 intptr_t rs_val = get_register(rs);
2040 uint32_t im_val =
instr->Bits(15, 0);
2041 intptr_t alu_out = rs_val ^ im_val;
2042 set_register(ra, alu_out);
2047 int rs =
instr->RSValue();
2048 int ra =
instr->RAValue();
2049 intptr_t rs_val = get_register(rs);
2050 uint32_t im_val =
instr->Bits(15, 0);
2051 intptr_t alu_out = rs_val ^ (im_val << 16);
2052 set_register(ra, alu_out);
2056 int rs =
instr->RSValue();
2057 int ra =
instr->RAValue();
2058 intptr_t rs_val = get_register(rs);
2059 uint32_t im_val =
instr->Bits(15, 0);
2060 intptr_t alu_out = rs_val & im_val;
2061 set_register(ra, alu_out);
2066 int rs =
instr->RSValue();
2067 int ra =
instr->RAValue();
2068 intptr_t rs_val = get_register(rs);
2069 uint32_t im_val =
instr->Bits(15, 0);
2070 intptr_t alu_out = rs_val & (im_val << 16);
2071 set_register(ra, alu_out);
2076 int rs =
instr->RSValue();
2077 int ra =
instr->RAValue();
2078 int rb =
instr->RBValue();
2079 uint32_t rs_val = get_register(rs);
2080 uintptr_t rb_val = get_register(rb) & 0x3F;
2081 intptr_t
result = (rb_val > 31) ? 0 : rs_val >> rb_val;
2082 set_register(ra,
result);
2083 if (
instr->Bit(0)) {
2089 int rs =
instr->RSValue();
2090 int ra =
instr->RAValue();
2091 int rb =
instr->RBValue();
2092 uintptr_t rs_val = get_register(rs);
2093 uintptr_t rb_val = get_register(rb) & 0x7F;
2094 intptr_t
result = (rb_val > 63) ? 0 : rs_val >> rb_val;
2095 set_register(ra,
result);
2096 if (
instr->Bit(0)) {
2102 int rt =
instr->RTValue();
2103 int ra =
instr->RAValue();
2104 int rb =
instr->RBValue();
2105 uint32_t ra_val = get_register(ra);
2106 uint32_t rb_val = get_register(rb);
2107 uint32_t alu_out = (rb_val == 0) ? -1 : ra_val % rb_val;
2108 set_register(rt, alu_out);
2112 int rt =
instr->RTValue();
2113 int ra =
instr->RAValue();
2114 int rb =
instr->RBValue();
2115 uint64_t ra_val = get_register(ra);
2116 uint64_t rb_val = get_register(rb);
2117 uint64_t alu_out = (rb_val == 0) ? -1 : ra_val % rb_val;
2118 set_register(rt, alu_out);
2122 int rt =
instr->RTValue();
2123 int ra =
instr->RAValue();
2124 int rb =
instr->RBValue();
2125 int32_t ra_val = get_register(ra);
2126 int32_t rb_val = get_register(rb);
2127 bool overflow = (ra_val ==
kMinInt && rb_val == -1);
2131 set_register(rt, alu_out);
2135 int rt =
instr->RTValue();
2136 int ra =
instr->RAValue();
2137 int rb =
instr->RBValue();
2138 int64_t ra_val = get_register(ra);
2139 int64_t rb_val = get_register(rb);
2141 int64_t kMinLongLong = (
one << 63);
2145 (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1))
2148 set_register(rt, alu_out);
2152 int rs =
instr->RSValue();
2153 int ra =
instr->RAValue();
2154 int rb =
instr->RBValue();
2155 int32_t rs_val = get_register(rs);
2156 intptr_t rb_val = get_register(rb) & 0x3F;
2157 intptr_t
result = (rb_val > 31) ? rs_val >> 31 : rs_val >> rb_val;
2158 set_register(ra,
result);
2159 if (
instr->Bit(0)) {
2165 int rs =
instr->RSValue();
2166 int ra =
instr->RAValue();
2167 int rb =
instr->RBValue();
2168 intptr_t rs_val = get_register(rs);
2169 intptr_t rb_val = get_register(rb) & 0x7F;
2170 intptr_t
result = (rb_val > 63) ? rs_val >> 63 : rs_val >> rb_val;
2171 set_register(ra,
result);
2172 if (
instr->Bit(0)) {
2178 int ra =
instr->RAValue();
2179 int rs =
instr->RSValue();
2180 int sh =
instr->Bits(15, 11);
2181 int32_t rs_val = get_register(rs);
2182 intptr_t
result = rs_val >> sh;
2183 set_register(ra,
result);
2184 if (
instr->Bit(0)) {
2191 int ra =
instr->RAValue();
2192 int rs =
instr->RSValue();
2193 intptr_t rs_val = get_register(rs);
2194 intptr_t ra_val = (rs_val << shift) >> shift;
2195 set_register(ra, ra_val);
2196 if (
instr->Bit(0)) {
2203 int ra =
instr->RAValue();
2204 int rs =
instr->RSValue();
2205 intptr_t rs_val = get_register(rs);
2206 intptr_t ra_val = (rs_val << shift) >> shift;
2207 set_register(ra, ra_val);
2208 if (
instr->Bit(0)) {
2215 int ra =
instr->RAValue();
2216 int rs =
instr->RSValue();
2217 intptr_t rs_val = get_register(rs);
2218 intptr_t ra_val = (rs_val << shift) >> shift;
2219 set_register(ra, ra_val);
2220 if (
instr->Bit(0)) {
2227 int frt =
instr->RTValue();
2228 int ra =
instr->RAValue();
2229 int rb =
instr->RBValue();
2230 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2231 intptr_t rb_val = get_register(rb);
2232 int32_t val = ReadW(ra_val + rb_val);
2233 float* fptr =
reinterpret_cast<float*
>(&val);
2234#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
2236 if ((val & 0x7F800000) == 0x7F800000) {
2237 int64_t dval =
static_cast<int64_t
>(val);
2238 dval = ((dval & 0xC0000000) << 32) | ((dval & 0x40000000) << 31) |
2239 ((dval & 0x40000000) << 30) | ((dval & 0x7FFFFFFF) << 29) | 0x0;
2240 set_d_register(frt, dval);
2242 set_d_register_from_double(frt,
static_cast<double>(*fptr));
2245 set_d_register_from_double(frt,
static_cast<double>(*fptr));
2247 if (opcode == LFSUX) {
2249 set_register(ra, ra_val + rb_val);
2255 int frt =
instr->RTValue();
2256 int ra =
instr->RAValue();
2257 int rb =
instr->RBValue();
2258 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2259 intptr_t rb_val = get_register(rb);
2260 int64_t dptr = ReadDW(ra_val + rb_val);
2261 set_d_register(frt, dptr);
2262 if (opcode == LFDUX) {
2264 set_register(ra, ra_val + rb_val);
2271 int frs =
instr->RSValue();
2272 int ra =
instr->RAValue();
2273 int rb =
instr->RBValue();
2274 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2275 intptr_t rb_val = get_register(rb);
2276 float frs_val =
static_cast<float>(get_double_from_d_register(frs));
2278#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
2281 int64_t dval = get_d_register(frs);
2282 if ((dval & 0x7FF0000000000000) == 0x7FF0000000000000) {
2283 sval = ((dval & 0xC000000000000000) >> 32) |
2284 ((dval & 0x07FFFFFFE0000000) >> 29);
2287 p =
reinterpret_cast<int32_t*
>(&frs_val);
2290 p =
reinterpret_cast<int32_t*
>(&frs_val);
2292 WriteW(ra_val + rb_val, *p);
2293 if (opcode == STFSUX) {
2295 set_register(ra, ra_val + rb_val);
2302 int frs =
instr->RSValue();
2303 int ra =
instr->RAValue();
2304 int rb =
instr->RBValue();
2305 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2306 intptr_t rb_val = get_register(rb);
2307 int64_t frs_val = get_d_register(frs);
2308 WriteDW(ra_val + rb_val, frs_val);
2309 if (opcode == STFDUX) {
2311 set_register(ra, ra_val + rb_val);
2316 int rs =
instr->RSValue();
2317 int ra =
instr->RAValue();
2318 uintptr_t rs_val = get_register(rs);
2319 uintptr_t count = 0;
2321 uintptr_t bit = 0x80000000;
2322 for (; n < 32; n++) {
2323 if (bit & rs_val) count++;
2326 set_register(ra, count);
2330 int rs =
instr->RSValue();
2331 int ra =
instr->RAValue();
2332 uintptr_t rs_val = get_register(rs);
2333 uintptr_t count = 0;
2335 uintptr_t bit = 0x8000000000000000UL;
2336 for (; n < 64; n++) {
2337 if (bit & rs_val) count++;
2340 set_register(ra, count);
2345 __sync_synchronize();
2355 int ra =
instr->RAValue();
2356 int rt =
instr->RTValue();
2357 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2359 set_register(rt, ReadWU(ra_val +
offset));
2360 if (opcode == LWZU) {
2362 set_register(ra, ra_val +
offset);
2369 int ra =
instr->RAValue();
2370 int rt =
instr->RTValue();
2371 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2373 set_register(rt, ReadB(ra_val +
offset) & 0xFF);
2374 if (opcode == LBZU) {
2376 set_register(ra, ra_val +
offset);
2383 int ra =
instr->RAValue();
2384 int rs =
instr->RSValue();
2385 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2386 int32_t rs_val = get_register(rs);
2388 WriteW(ra_val +
offset, rs_val);
2389 if (opcode == STWU) {
2391 set_register(ra, ra_val +
offset);
2396 int ra =
instr->RAValue();
2397 int rs =
instr->RSValue();
2398 int sh = (
instr->Bits(15, 11) | (
instr->Bit(1) << 5));
2399 intptr_t rs_val = get_register(rs);
2400 intptr_t
result = rs_val >> sh;
2401 set_register(ra,
result);
2402 if (
instr->Bit(0)) {
2408 int rs =
instr->RSValue();
2409 int ra =
instr->RAValue();
2410 int rb =
instr->RBValue();
2411 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2412 int8_t rs_val = get_register(rs);
2413 intptr_t rb_val = get_register(rb);
2414 SetCR0(WriteExB(ra_val + rb_val, rs_val));
2418 int rs =
instr->RSValue();
2419 int ra =
instr->RAValue();
2420 int rb =
instr->RBValue();
2421 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2422 int16_t rs_val = get_register(rs);
2423 intptr_t rb_val = get_register(rb);
2424 SetCR0(WriteExH(ra_val + rb_val, rs_val));
2428 int rs =
instr->RSValue();
2429 int ra =
instr->RAValue();
2430 int rb =
instr->RBValue();
2431 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2432 int32_t rs_val = get_register(rs);
2433 intptr_t rb_val = get_register(rb);
2434 SetCR0(WriteExW(ra_val + rb_val, rs_val));
2438 int rs =
instr->RSValue();
2439 int ra =
instr->RAValue();
2440 int rb =
instr->RBValue();
2441 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
2442 int64_t rs_val = get_register(rs);
2443 intptr_t rb_val = get_register(rb);
2444 SetCR0(WriteExDW(ra_val + rb_val, rs_val));
2449 SoftwareInterrupt(
instr);
2453 int ra =
instr->RAValue();
2454 int rb =
instr->RBValue();
2455 int cr =
instr->Bits(25, 23);
2459 intptr_t ra_val = get_register(ra);
2460 intptr_t rb_val = get_register(rb);
2461 if (ra_val < rb_val) {
2464 if (ra_val > rb_val) {
2467 if (ra_val == rb_val) {
2471 int32_t ra_val = get_register(ra);
2472 int32_t rb_val = get_register(rb);
2473 if (ra_val < rb_val) {
2476 if (ra_val > rb_val) {
2479 if (ra_val == rb_val) {
2483 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
2485 condition_reg_ = (condition_reg_ & ~condition_mask) |
condition;
2489 int rt =
instr->RTValue();
2490 int ra =
instr->RAValue();
2491 int rb =
instr->RBValue();
2493 uintptr_t ra_val = get_register(ra);
2494 uintptr_t rb_val = get_register(rb);
2495 uintptr_t alu_out = ~ra_val + rb_val + 1;
2497 if (ra_val <= rb_val) {
2498 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
2500 special_reg_xer_ &= ~0xF0000000;
2502 set_register(rt, alu_out);
2503 if (
instr->Bit(0)) {
2510 int rt =
instr->RTValue();
2511 int ra =
instr->RAValue();
2512 int rb =
instr->RBValue();
2514 uintptr_t ra_val = get_register(ra);
2515 uintptr_t rb_val = get_register(rb);
2516 uintptr_t alu_out = ~ra_val + rb_val;
2517 if (special_reg_xer_ & 0x20000000) {
2520 set_register(rt, alu_out);
2521 if (
instr->Bit(0)) {
2522 SetCR0(
static_cast<intptr_t
>(alu_out));
2528 int rt =
instr->RTValue();
2529 int ra =
instr->RAValue();
2530 int rb =
instr->RBValue();
2532 uintptr_t ra_val = get_register(ra);
2533 uintptr_t rb_val = get_register(rb);
2534 uintptr_t alu_out = ra_val + rb_val;
2536 if (~ra_val < rb_val) {
2537 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
2539 special_reg_xer_ &= ~0xF0000000;
2541 set_register(rt, alu_out);
2542 if (
instr->Bit(0)) {
2543 SetCR0(
static_cast<intptr_t
>(alu_out));
2549 int rt =
instr->RTValue();
2550 int ra =
instr->RAValue();
2551 int rb =
instr->RBValue();
2553 uintptr_t ra_val = get_register(ra);
2554 uintptr_t rb_val = get_register(rb);
2555 uintptr_t alu_out = ra_val + rb_val;
2556 if (special_reg_xer_ & 0x20000000) {
2559 set_register(rt, alu_out);
2560 if (
instr->Bit(0)) {
2561 SetCR0(
static_cast<intptr_t
>(alu_out));
2567 int rt =
instr->RTValue();
2568 int ra =
instr->RAValue();
2569 int rb =
instr->RBValue();
2570 int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2571 int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2572 int64_t alu_out = (int64_t)ra_val * (int64_t)rb_val;
2575 alu_out = (alu_out >> 32) | 0x421000000000000;
2576 set_register(rt, alu_out);
2577 if (
instr->Bit(0)) {
2578 SetCR0(
static_cast<intptr_t
>(alu_out));
2583 int rt =
instr->RTValue();
2584 int ra =
instr->RAValue();
2585 int rb =
instr->RBValue();
2586 uint32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2587 uint32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2588 uint64_t alu_out = (uint64_t)ra_val * (uint64_t)rb_val;
2591 alu_out = (alu_out >> 32) | 0x421000000000000;
2592 set_register(rt, alu_out);
2593 if (
instr->Bit(0)) {
2594 SetCR0(
static_cast<intptr_t
>(alu_out));
2599 int rt =
instr->RTValue();
2600 int ra =
instr->RAValue();
2601 int rb =
instr->RBValue();
2602 int64_t ra_val = get_register(ra);
2603 int64_t rb_val = get_register(rb);
2604 int64_t alu_out = base::bits::SignedMulHigh64(ra_val, rb_val);
2605 set_register(rt, alu_out);
2606 if (
instr->Bit(0)) {
2607 SetCR0(
static_cast<intptr_t
>(alu_out));
2612 int rt =
instr->RTValue();
2613 int ra =
instr->RAValue();
2614 int rb =
instr->RBValue();
2615 uint64_t ra_val = get_register(ra);
2616 uint64_t rb_val = get_register(rb);
2617 uint64_t alu_out = base::bits::UnsignedMulHigh64(ra_val, rb_val);
2618 set_register(rt, alu_out);
2619 if (
instr->Bit(0)) {
2620 SetCR0(
static_cast<intptr_t
>(alu_out));
2625 int rt =
instr->RTValue();
2626 int ra =
instr->RAValue();
2627 intptr_t ra_val = get_register(ra);
2628 intptr_t alu_out = 1 + ~ra_val;
2630 intptr_t kOverflowVal = (
one << 63);
2631 set_register(rt, alu_out);
2632 if (
instr->Bit(10)) {
2633 if (ra_val == kOverflowVal) {
2634 special_reg_xer_ |= 0xC0000000;
2636 special_reg_xer_ &= ~0x40000000;
2639 if (
instr->Bit(0)) {
2640 bool setSO = (special_reg_xer_ & 0x80000000);
2641 SetCR0(alu_out, setSO);
2646 int rs =
instr->RSValue();
2647 int ra =
instr->RAValue();
2648 int rb =
instr->RBValue();
2649 uint32_t rs_val = get_register(rs);
2650 uintptr_t rb_val = get_register(rb) & 0x3F;
2651 uint32_t
result = (rb_val > 31) ? 0 : rs_val << rb_val;
2652 set_register(ra,
result);
2653 if (
instr->Bit(0)) {
2659 int rs =
instr->RSValue();
2660 int ra =
instr->RAValue();
2661 int rb =
instr->RBValue();
2662 uintptr_t rs_val = get_register(rs);
2663 uintptr_t rb_val = get_register(rb) & 0x7F;
2664 uintptr_t
result = (rb_val > 63) ? 0 : rs_val << rb_val;
2665 set_register(ra,
result);
2666 if (
instr->Bit(0)) {
2672 int frt =
instr->RTValue();
2673 int ra =
instr->RAValue();
2675 if (!
instr->Bit(0)) {
2677 frt_val = get_d_register(frt);
2681 frt_val = get_simd_register_by_lane<int64_t>(frt, 0);
2683 set_register(ra, frt_val);
2688 int frt =
instr->RTValue();
2689 int ra =
instr->RAValue();
2690 int64_t frt_val = get_d_register(frt);
2691 set_register(ra,
static_cast<uint32_t
>(frt_val));
2695 int frt =
instr->RTValue();
2696 int ra =
instr->RAValue();
2697 int64_t ra_val = get_register(ra);
2698 if (!
instr->Bit(0)) {
2700 set_d_register(frt, ra_val);
2704 set_simd_register_by_lane<int64_t>(frt, 0,
2705 static_cast<int64_t
>(ra_val));
2708 set_simd_register_by_lane<int64_t>(
2709 frt, 1,
static_cast<int64_t
>(0x123456789ABCD));
2714 int xt =
instr->RTValue();
2715 int ra =
instr->RAValue();
2716 int rb =
instr->RBValue();
2717 set_simd_register_by_lane<int64_t>(
2718 xt, 0,
static_cast<int64_t
>(get_register(ra)));
2719 set_simd_register_by_lane<int64_t>(
2720 xt, 1,
static_cast<int64_t
>(get_register(rb)));
2725 int frt =
instr->RTValue();
2726 int ra =
instr->RAValue();
2727 int64_t ra_val =
static_cast<int32_t>(get_register(ra));
2728 set_d_register(frt, ra_val);
2733 int frt =
instr->RTValue();
2734 int ra =
instr->RAValue();
2735 uint64_t ra_val =
static_cast<uint32_t
>(get_register(ra));
2736 set_d_register(frt, ra_val);
2740 int rs =
instr->RSValue();
2741 int ra =
instr->RAValue();
2742 uintptr_t rs_val = get_register(rs);
2743 uintptr_t count = 0;
2745 uintptr_t bit = 0x80000000;
2746 for (; n < 32; n++) {
2747 if (bit & rs_val)
break;
2751 set_register(ra, count);
2752 if (
instr->Bit(0)) {
2760 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2765 int rs =
instr->RSValue();
2766 int ra =
instr->RAValue();
2767 uintptr_t rs_val = get_register(rs);
2768 uintptr_t count = 0;
2770 uintptr_t bit = 0x8000000000000000UL;
2771 for (; n < 64; n++) {
2772 if (bit & rs_val)
break;
2776 set_register(ra, count);
2777 if (
instr->Bit(0)) {
2785 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2790 int rs =
instr->RSValue();
2791 int ra =
instr->RAValue();
2792 uint32_t rs_val =
static_cast<uint32_t
>(get_register(rs));
2793 uintptr_t count = rs_val == 0 ? 32 : __builtin_ctz(rs_val);
2794 set_register(ra, count);
2795 if (
instr->Bit(0)) {
2803 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2808 int rs =
instr->RSValue();
2809 int ra =
instr->RAValue();
2810 uint64_t rs_val = get_register(rs);
2811 uintptr_t count = rs_val == 0 ? 64 : __builtin_ctzl(rs_val);
2812 set_register(ra, count);
2813 if (
instr->Bit(0)) {
2821 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
2826 int rs =
instr->RSValue();
2827 int ra =
instr->RAValue();
2828 int rb =
instr->RBValue();
2829 intptr_t rs_val = get_register(rs);
2830 intptr_t rb_val = get_register(rb);
2831 intptr_t alu_out = rs_val & rb_val;
2832 set_register(ra, alu_out);
2833 if (
instr->Bit(0)) {
2839 int rs =
instr->RSValue();
2840 int ra =
instr->RAValue();
2841 int rb =
instr->RBValue();
2842 intptr_t rs_val = get_register(rs);
2843 intptr_t rb_val = get_register(rb);
2844 intptr_t alu_out = rs_val & ~rb_val;
2845 set_register(ra, alu_out);
2846 if (
instr->Bit(0)) {
2852 int ra =
instr->RAValue();
2853 int rb =
instr->RBValue();
2854 int cr =
instr->Bits(25, 23);
2858 uintptr_t ra_val = get_register(ra);
2859 uintptr_t rb_val = get_register(rb);
2860 if (ra_val < rb_val) {
2863 if (ra_val > rb_val) {
2866 if (ra_val == rb_val) {
2870 uint32_t ra_val = get_register(ra);
2871 uint32_t rb_val = get_register(rb);
2872 if (ra_val < rb_val) {
2875 if (ra_val > rb_val) {
2878 if (ra_val == rb_val) {
2882 uint32_t condition_mask = 0xF0000000U >> (cr * 4);
2884 condition_reg_ = (condition_reg_ & ~condition_mask) |
condition;
2888 int rt =
instr->RTValue();
2889 int ra =
instr->RAValue();
2890 int rb =
instr->RBValue();
2892 intptr_t ra_val = get_register(ra);
2893 intptr_t rb_val = get_register(rb);
2894 intptr_t alu_out = rb_val - ra_val;
2896 set_register(rt, alu_out);
2897 if (
instr->Bit(0)) {
2904 int rt =
instr->RTValue();
2905 int ra =
instr->RAValue();
2906 intptr_t ra_val = get_register(ra);
2907 if (special_reg_xer_ & 0x20000000) {
2910 set_register(rt, ra_val);
2911 if (
instr->Bit(0)) {
2918 int rs =
instr->RSValue();
2919 int ra =
instr->RAValue();
2920 int rb =
instr->RBValue();
2921 intptr_t rs_val = get_register(rs);
2922 intptr_t rb_val = get_register(rb);
2923 intptr_t alu_out = ~(rs_val | rb_val);
2924 set_register(ra, alu_out);
2925 if (
instr->Bit(0)) {
2931 int rt =
instr->RTValue();
2932 int ra =
instr->RAValue();
2933 int rb =
instr->RBValue();
2934 int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
2935 int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
2936 int32_t alu_out = ra_val * rb_val;
2937 set_register(rt, alu_out);
2938 if (
instr->Bit(0)) {
2945 int rt =
instr->RTValue();
2946 int ra =
instr->RAValue();
2947 int rb =
instr->RBValue();
2948 int64_t ra_val = get_register(ra);
2949 int64_t rb_val = get_register(rb);
2950 int64_t alu_out = ra_val * rb_val;
2951 set_register(rt, alu_out);
2952 if (
instr->Bit(0)) {
2959 int rt =
instr->RTValue();
2960 int ra =
instr->RAValue();
2961 int rb =
instr->RBValue();
2962 int32_t ra_val = get_register(ra);
2963 int32_t rb_val = get_register(rb);
2964 bool overflow = (ra_val ==
kMinInt && rb_val == -1);
2968 set_register(rt, alu_out);
2969 if (
instr->Bit(10)) {
2971 special_reg_xer_ |= 0xC0000000;
2973 special_reg_xer_ &= ~0x40000000;
2976 if (
instr->Bit(0)) {
2977 bool setSO = (special_reg_xer_ & 0x80000000);
2978 SetCR0(alu_out, setSO);
2983 int rt =
instr->RTValue();
2984 int ra =
instr->RAValue();
2985 int rb =
instr->RBValue();
2986 uint32_t ra_val = get_register(ra);
2987 uint32_t rb_val = get_register(rb);
2988 bool overflow = (rb_val == 0);
2990 uint32_t alu_out = (
overflow) ? -1 : ra_val / rb_val;
2991 set_register(rt, alu_out);
2992 if (
instr->Bit(10)) {
2994 special_reg_xer_ |= 0xC0000000;
2996 special_reg_xer_ &= ~0x40000000;
2999 if (
instr->Bit(0)) {
3000 bool setSO = (special_reg_xer_ & 0x80000000);
3001 SetCR0(alu_out, setSO);
3006 int rt =
instr->RTValue();
3007 int ra =
instr->RAValue();
3008 int rb =
instr->RBValue();
3009 int64_t ra_val = get_register(ra);
3010 int64_t rb_val = get_register(rb);
3012 int64_t kMinLongLong = (
one << 63);
3016 (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1))
3019 set_register(rt, alu_out);
3020 if (
instr->Bit(0)) {
3027 int rt =
instr->RTValue();
3028 int ra =
instr->RAValue();
3029 int rb =
instr->RBValue();
3030 uint64_t ra_val = get_register(ra);
3031 uint64_t rb_val = get_register(rb);
3033 uint64_t alu_out = (rb_val == 0) ? -1 : ra_val / rb_val;
3034 set_register(rt, alu_out);
3035 if (
instr->Bit(0)) {
3042 int rt =
instr->RTValue();
3043 int ra =
instr->RAValue();
3044 int rb =
instr->RBValue();
3046 intptr_t ra_val = get_register(ra);
3047 intptr_t rb_val = get_register(rb);
3048 intptr_t alu_out = ra_val + rb_val;
3049 set_register(rt, alu_out);
3050 if (
instr->Bit(0)) {
3057 int rs =
instr->RSValue();
3058 int ra =
instr->RAValue();
3059 int rb =
instr->RBValue();
3060 intptr_t rs_val = get_register(rs);
3061 intptr_t rb_val = get_register(rb);
3062 intptr_t alu_out = rs_val ^ rb_val;
3063 set_register(ra, alu_out);
3064 if (
instr->Bit(0)) {
3070 int rs =
instr->RSValue();
3071 int ra =
instr->RAValue();
3072 int rb =
instr->RBValue();
3073 intptr_t rs_val = get_register(rs);
3074 intptr_t rb_val = get_register(rb);
3075 intptr_t alu_out = rs_val | rb_val;
3076 set_register(ra, alu_out);
3077 if (
instr->Bit(0)) {
3083 int rs =
instr->RSValue();
3084 int ra =
instr->RAValue();
3085 int rb =
instr->RBValue();
3086 intptr_t rs_val = get_register(rs);
3087 intptr_t rb_val = get_register(rb);
3088 intptr_t alu_out = rs_val | ~rb_val;
3089 set_register(ra, alu_out);
3090 if (
instr->Bit(0)) {
3096 int rt =
instr->RTValue();
3097 int spr =
instr->Bits(20, 11);
3101 set_register(rt, special_reg_lr_);
3105 int rt =
instr->RTValue();
3106 intptr_t rt_val = get_register(rt);
3107 int spr =
instr->Bits(20, 11);
3109 special_reg_lr_ = rt_val;
3110 }
else if (spr == 288) {
3111 special_reg_ctr_ = rt_val;
3112 }
else if (spr == 32) {
3113 special_reg_xer_ = rt_val;
3120 int rt =
instr->RTValue();
3121 set_register(rt, condition_reg_);
3126 int rs =
instr->RSValue();
3127 int ra =
instr->RAValue();
3128 int rb =
instr->RBValue();
3129 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3130 int32_t rs_val = get_register(rs);
3131 intptr_t rb_val = get_register(rb);
3132 WriteW(ra_val + rb_val, rs_val);
3133 if (opcode == STWUX) {
3135 set_register(ra, ra_val + rb_val);
3141 int rs =
instr->RSValue();
3142 int ra =
instr->RAValue();
3143 int rb =
instr->RBValue();
3144 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3145 int8_t rs_val = get_register(rs);
3146 intptr_t rb_val = get_register(rb);
3147 WriteB(ra_val + rb_val, rs_val);
3148 if (opcode == STBUX) {
3150 set_register(ra, ra_val + rb_val);
3156 int rs =
instr->RSValue();
3157 int ra =
instr->RAValue();
3158 int rb =
instr->RBValue();
3159 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3160 int16_t rs_val = get_register(rs);
3161 intptr_t rb_val = get_register(rb);
3162 WriteH(ra_val + rb_val, rs_val);
3163 if (opcode == STHUX) {
3165 set_register(ra, ra_val + rb_val);
3171 int rt =
instr->RTValue();
3172 int ra =
instr->RAValue();
3173 int rb =
instr->RBValue();
3174 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3175 intptr_t rb_val = get_register(rb);
3176 set_register(rt, ReadWU(ra_val + rb_val));
3177 if (opcode == LWZUX) {
3178 DCHECK(ra != 0 && ra != rt);
3179 set_register(ra, ra_val + rb_val);
3184 int rt =
instr->RTValue();
3185 int ra =
instr->RAValue();
3186 int rb =
instr->RBValue();
3187 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3188 intptr_t rb_val = get_register(rb);
3189 set_register(rt, ReadW(ra_val + rb_val));
3194 int rt =
instr->RTValue();
3195 int ra =
instr->RAValue();
3196 int rb =
instr->RBValue();
3197 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3198 intptr_t rb_val = get_register(rb);
3199 intptr_t
result = ReadDW(ra_val + rb_val);
3200 set_register(rt,
result);
3201 if (opcode == LDUX) {
3202 DCHECK(ra != 0 && ra != rt);
3203 set_register(ra, ra_val + rb_val);
3208 int rt =
instr->RTValue();
3209 int ra =
instr->RAValue();
3210 int rb =
instr->RBValue();
3211 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3212 intptr_t rb_val = get_register(rb);
3213 intptr_t
result = ByteReverse<int64_t>(ReadDW(ra_val + rb_val));
3214 set_register(rt,
result);
3218 int rt =
instr->RTValue();
3219 int ra =
instr->RAValue();
3220 int rb =
instr->RBValue();
3221 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3222 intptr_t rb_val = get_register(rb);
3223 intptr_t
result = ByteReverse<int32_t>(ReadW(ra_val + rb_val));
3224 set_register(rt,
result);
3228 int rs =
instr->RSValue();
3229 int ra =
instr->RAValue();
3230 int rb =
instr->RBValue();
3231 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3232 intptr_t rs_val = get_register(rs);
3233 intptr_t rb_val = get_register(rb);
3234 WriteDW(ra_val + rb_val, ByteReverse<int64_t>(rs_val));
3238 int rs =
instr->RSValue();
3239 int ra =
instr->RAValue();
3240 int rb =
instr->RBValue();
3241 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3242 intptr_t rs_val = get_register(rs);
3243 intptr_t rb_val = get_register(rb);
3244 WriteW(ra_val + rb_val, ByteReverse<int32_t>(rs_val));
3248 int rs =
instr->RSValue();
3249 int ra =
instr->RAValue();
3250 int rb =
instr->RBValue();
3251 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3252 intptr_t rs_val = get_register(rs);
3253 intptr_t rb_val = get_register(rb);
3254 WriteH(ra_val + rb_val, ByteReverse<int16_t>(rs_val));
3259 int rs =
instr->RSValue();
3260 int ra =
instr->RAValue();
3261 int rb =
instr->RBValue();
3262 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3263 intptr_t rs_val = get_register(rs);
3264 intptr_t rb_val = get_register(rb);
3265 WriteDW(ra_val + rb_val, rs_val);
3266 if (opcode == STDUX) {
3268 set_register(ra, ra_val + rb_val);
3274 int rt =
instr->RTValue();
3275 int ra =
instr->RAValue();
3276 int rb =
instr->RBValue();
3277 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3278 intptr_t rb_val = get_register(rb);
3279 set_register(rt, ReadBU(ra_val + rb_val) & 0xFF);
3280 if (opcode == LBZUX) {
3281 DCHECK(ra != 0 && ra != rt);
3282 set_register(ra, ra_val + rb_val);
3288 int rt =
instr->RTValue();
3289 int ra =
instr->RAValue();
3290 int rb =
instr->RBValue();
3291 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3292 intptr_t rb_val = get_register(rb);
3293 set_register(rt, ReadHU(ra_val + rb_val) & 0xFFFF);
3294 if (opcode == LHZUX) {
3295 DCHECK(ra != 0 && ra != rt);
3296 set_register(ra, ra_val + rb_val);
3301 int rt =
instr->RTValue();
3302 int ra =
instr->RAValue();
3303 int rb =
instr->RBValue();
3304 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3305 intptr_t rb_val = get_register(rb);
3306 set_register(rt, ReadH(ra_val + rb_val));
3310 int rt =
instr->RTValue();
3311 int ra =
instr->RAValue();
3312 int rb =
instr->RBValue();
3313 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3314 intptr_t rb_val = get_register(rb);
3315 set_register(rt, ReadExBU(ra_val + rb_val) & 0xFF);
3319 int rt =
instr->RTValue();
3320 int ra =
instr->RAValue();
3321 int rb =
instr->RBValue();
3322 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3323 intptr_t rb_val = get_register(rb);
3324 set_register(rt, ReadExHU(ra_val + rb_val));
3328 int rt =
instr->RTValue();
3329 int ra =
instr->RAValue();
3330 int rb =
instr->RBValue();
3331 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3332 intptr_t rb_val = get_register(rb);
3333 set_register(rt, ReadExWU(ra_val + rb_val));
3337 int rt =
instr->RTValue();
3338 int ra =
instr->RAValue();
3339 int rb =
instr->RBValue();
3340 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3341 intptr_t rb_val = get_register(rb);
3342 set_register(rt, ReadExDWU(ra_val + rb_val));
3350 int rt =
instr->RTValue();
3351 int ra =
instr->RAValue();
3352 int rb =
instr->RBValue();
3353 int condition_bit =
instr->RCValue();
3354 int condition_mask = 0x80000000 >> condition_bit;
3355 intptr_t ra_val = (ra == 0) ? 0 : get_register(ra);
3356 intptr_t rb_val = get_register(rb);
3357 intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val;
3358 set_register(rt, value);
3364 int ra =
instr->RAValue();
3365 int rs =
instr->RSValue();
3366 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3367 int8_t rs_val = get_register(rs);
3369 WriteB(ra_val +
offset, rs_val);
3370 if (opcode == STBU) {
3372 set_register(ra, ra_val +
offset);
3379 int ra =
instr->RAValue();
3380 int rt =
instr->RTValue();
3381 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3384 set_register(rt,
result);
3385 if (opcode == LHZU) {
3386 set_register(ra, ra_val +
offset);
3393 int ra =
instr->RAValue();
3394 int rt =
instr->RTValue();
3395 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3398 set_register(rt,
result);
3399 if (opcode == LHAU) {
3400 set_register(ra, ra_val +
offset);
3407 int ra =
instr->RAValue();
3408 int rs =
instr->RSValue();
3409 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3410 int16_t rs_val = get_register(rs);
3412 WriteH(ra_val +
offset, rs_val);
3413 if (opcode == STHU) {
3415 set_register(ra, ra_val +
offset);
3427 int frt =
instr->RTValue();
3428 int ra =
instr->RAValue();
3430 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3432 float* fptr =
reinterpret_cast<float*
>(&val);
3433#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
3435 if ((val & 0x7F800000) == 0x7F800000) {
3436 int64_t dval =
static_cast<int64_t
>(val);
3437 dval = ((dval & 0xC0000000) << 32) | ((dval & 0x40000000) << 31) |
3438 ((dval & 0x40000000) << 30) | ((dval & 0x7FFFFFFF) << 29) | 0x0;
3439 set_d_register(frt, dval);
3441 set_d_register_from_double(frt,
static_cast<double>(*fptr));
3444 set_d_register_from_double(frt,
static_cast<double>(*fptr));
3446 if (opcode == LFSU) {
3448 set_register(ra, ra_val +
offset);
3455 int frt =
instr->RTValue();
3456 int ra =
instr->RAValue();
3458 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3459 int64_t dptr = ReadDW(ra_val +
offset);
3460 set_d_register(frt, dptr);
3461 if (opcode == LFDU) {
3463 set_register(ra, ra_val +
offset);
3471 int frs =
instr->RSValue();
3472 int ra =
instr->RAValue();
3474 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3475 float frs_val =
static_cast<float>(get_double_from_d_register(frs));
3477#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
3480 int64_t dval = get_d_register(frs);
3481 if ((dval & 0x7FF0000000000000) == 0x7FF0000000000000) {
3482 sval = ((dval & 0xC000000000000000) >> 32) |
3483 ((dval & 0x07FFFFFFE0000000) >> 29);
3486 p =
reinterpret_cast<int32_t*
>(&frs_val);
3489 p =
reinterpret_cast<int32_t*
>(&frs_val);
3491 WriteW(ra_val +
offset, *p);
3492 if (opcode == STFSU) {
3494 set_register(ra, ra_val +
offset);
3500 int frs =
instr->RSValue();
3501 int ra =
instr->RAValue();
3503 intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
3504 int64_t frs_val = get_d_register(frs);
3505 WriteDW(ra_val +
offset, frs_val);
3506 if (opcode == STFDU) {
3508 set_register(ra, ra_val +
offset);
3513 constexpr int kBitsPerWord = 32;
3514 int rs =
instr->RSValue();
3515 int ra =
instr->RAValue();
3516 uint64_t rs_val = get_register(rs);
3517 uint32_t rs_high = rs_val >> kBitsPerWord;
3518 uint32_t rs_low = (rs_val << kBitsPerWord) >> kBitsPerWord;
3519 uint64_t
result = ByteReverse<int32_t>(rs_high);
3521 set_register(ra,
result);
3525 int rs =
instr->RSValue();
3526 int ra =
instr->RAValue();
3527 uint64_t rs_val = get_register(rs);
3528 set_register(ra, ByteReverse<int64_t>(rs_val));
3533 int frt =
instr->RTValue();
3534 int frb =
instr->RBValue();
3535 int64_t frb_val = get_d_register(frb);
3536 double frt_val =
static_cast<float>(frb_val);
3537 set_d_register_from_double(frt, frt_val);
3542 int frt =
instr->RTValue();
3543 int frb =
instr->RBValue();
3544 uint64_t frb_val = get_d_register(frb);
3545 double frt_val =
static_cast<float>(frb_val);
3546 set_d_register_from_double(frt, frt_val);
3551 int frt =
instr->RTValue();
3552 int fra =
instr->RAValue();
3553 int frb =
instr->RBValue();
3554 double fra_val = get_double_from_d_register(fra);
3555 double frb_val = get_double_from_d_register(frb);
3556 double frt_val = fra_val / frb_val;
3557 set_d_register_from_double(frt, frt_val);
3561 int frt =
instr->RTValue();
3562 int fra =
instr->RAValue();
3563 int frb =
instr->RBValue();
3564 double fra_val = get_double_from_d_register(fra);
3565 double frb_val = get_double_from_d_register(frb);
3566 double frt_val = fra_val - frb_val;
3567 set_d_register_from_double(frt, frt_val);
3571 int frt =
instr->RTValue();
3572 int fra =
instr->RAValue();
3573 int frb =
instr->RBValue();
3574 double fra_val = get_double_from_d_register(fra);
3575 double frb_val = get_double_from_d_register(frb);
3576 double frt_val = fra_val + frb_val;
3577 set_d_register_from_double(frt, frt_val);
3581 int frt =
instr->RTValue();
3582 int frb =
instr->RBValue();
3583 double frb_val = get_double_from_d_register(frb);
3584 double frt_val = std::sqrt(frb_val);
3585 set_d_register_from_double(frt, frt_val);
3589 int frt =
instr->RTValue();
3590 int fra =
instr->RAValue();
3591 int frb =
instr->RBValue();
3592 int frc =
instr->RCValue();
3593 double fra_val = get_double_from_d_register(fra);
3594 double frb_val = get_double_from_d_register(frb);
3595 double frc_val = get_double_from_d_register(frc);
3596 double frt_val = ((fra_val >= 0.0) ? frc_val : frb_val);
3597 set_d_register_from_double(frt, frt_val);
3601 int frt =
instr->RTValue();
3602 int fra =
instr->RAValue();
3603 int frc =
instr->RCValue();
3604 double fra_val = get_double_from_d_register(fra);
3605 double frc_val = get_double_from_d_register(frc);
3606 double frt_val = fra_val * frc_val;
3607 set_d_register_from_double(frt, frt_val);
3611 int frt =
instr->RTValue();
3612 int fra =
instr->RAValue();
3613 int frb =
instr->RBValue();
3614 int frc =
instr->RCValue();
3615 double fra_val = get_double_from_d_register(fra);
3616 double frb_val = get_double_from_d_register(frb);
3617 double frc_val = get_double_from_d_register(frc);
3618 double frt_val = (fra_val * frc_val) - frb_val;
3619 set_d_register_from_double(frt, frt_val);
3623 int frt =
instr->RTValue();
3624 int fra =
instr->RAValue();
3625 int frb =
instr->RBValue();
3626 int frc =
instr->RCValue();
3627 double fra_val = get_double_from_d_register(fra);
3628 double frb_val = get_double_from_d_register(frb);
3629 double frc_val = get_double_from_d_register(frc);
3630 double frt_val = (fra_val * frc_val) + frb_val;
3631 set_d_register_from_double(frt, frt_val);
3635 int fra =
instr->RAValue();
3636 int frb =
instr->RBValue();
3637 double fra_val = get_double_from_d_register(fra);
3638 double frb_val = get_double_from_d_register(frb);
3639 int cr =
instr->Bits(25, 23);
3641 if (fra_val < frb_val) {
3644 if (fra_val > frb_val) {
3647 if (fra_val == frb_val) {
3650 if (std::isunordered(fra_val, frb_val)) {
3653 int condition_mask = 0xF0000000 >> (cr * 4);
3655 condition_reg_ = (condition_reg_ & ~condition_mask) |
condition;
3659 int frt =
instr->RTValue();
3660 int frb =
instr->RBValue();
3661 double frb_val = get_double_from_d_register(frb);
3662 double frt_val = std::round(frb_val);
3663 set_d_register_from_double(frt, frt_val);
3664 if (
instr->Bit(0)) {
3670 int frt =
instr->RTValue();
3671 int frb =
instr->RBValue();
3672 double frb_val = get_double_from_d_register(frb);
3673 double frt_val = std::trunc(frb_val);
3674 set_d_register_from_double(frt, frt_val);
3675 if (
instr->Bit(0)) {
3681 int frt =
instr->RTValue();
3682 int frb =
instr->RBValue();
3683 double frb_val = get_double_from_d_register(frb);
3684 double frt_val = std::ceil(frb_val);
3685 set_d_register_from_double(frt, frt_val);
3686 if (
instr->Bit(0)) {
3692 int frt =
instr->RTValue();
3693 int frb =
instr->RBValue();
3694 double frb_val = get_double_from_d_register(frb);
3695 double frt_val = std::floor(frb_val);
3696 set_d_register_from_double(frt, frt_val);
3697 if (
instr->Bit(0)) {
3703 int frt =
instr->RTValue();
3704 int frb =
instr->RBValue();
3707 double frb_val = get_double_from_d_register(frb);
3708 double frt_val =
static_cast<float>(frb_val);
3709 set_d_register_from_double(frt, frt_val);
3710 if (
instr->Bit(0)) {
3716 int frt =
instr->RTValue();
3717 int frb =
instr->RBValue();
3718 int64_t frb_val = get_d_register(frb);
3719 double frt_val =
static_cast<double>(frb_val);
3720 set_d_register_from_double(frt, frt_val);
3724 int frt =
instr->RTValue();
3725 int frb =
instr->RBValue();
3726 uint64_t frb_val = get_d_register(frb);
3727 double frt_val =
static_cast<double>(frb_val);
3728 set_d_register_from_double(frt, frt_val);
3733 int frt =
instr->RTValue();
3734 int frb =
instr->RBValue();
3735 double frb_val = get_double_from_d_register(frb);
3736 int mode = (opcode == FCTIDZ) ? kRoundToZero
3740 int64_t kMinVal = (
one << 63);
3741 int64_t kMaxVal = kMinVal - 1;
3742 bool invalid_convert =
false;
3744 if (std::isnan(frb_val)) {
3746 invalid_convert =
true;
3750 frb_val = std::trunc(frb_val);
3753 frb_val = std::ceil(frb_val);
3756 frb_val = std::floor(frb_val);
3761 if (frb_val <
static_cast<double>(kMinVal)) {
3763 invalid_convert =
true;
3764 }
else if (frb_val >=
static_cast<double>(kMaxVal)) {
3766 invalid_convert =
true;
3768 frt_val = (int64_t)frb_val;
3771 set_d_register(frt, frt_val);
3772 if (invalid_convert) SetFPSCR(VXCVI);
3777 int frt =
instr->RTValue();
3778 int frb =
instr->RBValue();
3779 double frb_val = get_double_from_d_register(frb);
3780 int mode = (opcode == FCTIDUZ)
3784 uint64_t kMinVal = 0;
3785 uint64_t kMaxVal = kMinVal - 1;
3786 bool invalid_convert =
false;
3788 if (std::isnan(frb_val)) {
3790 invalid_convert =
true;
3794 frb_val = std::trunc(frb_val);
3797 frb_val = std::ceil(frb_val);
3800 frb_val = std::floor(frb_val);
3805 if (frb_val <
static_cast<double>(kMinVal)) {
3807 invalid_convert =
true;
3808 }
else if (frb_val >=
static_cast<double>(kMaxVal)) {
3810 invalid_convert =
true;
3812 frt_val = (uint64_t)frb_val;
3815 set_d_register(frt, frt_val);
3816 if (invalid_convert) SetFPSCR(VXCVI);
3821 int frt =
instr->RTValue();
3822 int frb =
instr->RBValue();
3823 double frb_val = get_double_from_d_register(frb);
3824 int mode = (opcode == FCTIWZ) ? kRoundToZero
3829 bool invalid_convert =
false;
3831 if (std::isnan(frb_val)) {
3836 frb_val = std::trunc(frb_val);
3839 frb_val = std::ceil(frb_val);
3842 frb_val = std::floor(frb_val);
3845 double orig = frb_val;
3846 frb_val = lround(frb_val);
3848 if (std::fabs(frb_val - orig) == 0.5 && ((int64_t)frb_val % 2)) {
3849 frb_val += ((frb_val > 0) ? -1.0 : 1.0);
3856 if (frb_val < kMinVal) {
3858 invalid_convert =
true;
3859 }
else if (frb_val > kMaxVal) {
3861 invalid_convert =
true;
3863 frt_val = (int64_t)frb_val;
3866 set_d_register(frt, frt_val);
3867 if (invalid_convert) SetFPSCR(VXCVI);
3872 int frt =
instr->RTValue();
3873 int frb =
instr->RBValue();
3874 double frb_val = get_double_from_d_register(frb);
3875 int mode = (opcode == FCTIWUZ)
3881 bool invalid_convert =
false;
3883 if (std::isnan(frb_val)) {
3888 frb_val = std::trunc(frb_val);
3891 frb_val = std::ceil(frb_val);
3894 frb_val = std::floor(frb_val);
3899 if (frb_val < kMinVal) {
3901 invalid_convert =
true;
3902 }
else if (frb_val > kMaxVal) {
3904 invalid_convert =
true;
3906 frt_val = (uint64_t)frb_val;
3909 set_d_register(frt, frt_val);
3910 if (invalid_convert) SetFPSCR(VXCVI);
3914 int frt =
instr->RTValue();
3915 int frb =
instr->RBValue();
3916 double frb_val = get_double_from_d_register(frb);
3917 double frt_val = -frb_val;
3918 set_d_register_from_double(frt, frt_val);
3922 int frt =
instr->RTValue();
3923 int frb =
instr->RBValue();
3924 int fra =
instr->RAValue();
3925 double frb_val = get_double_from_d_register(frb);
3926 double fra_val = get_double_from_d_register(fra);
3927 double frt_val = std::copysign(frb_val, fra_val);
3928 set_d_register_from_double(frt, frt_val);
3932 int frt =
instr->RTValue();
3933 int frb =
instr->RBValue();
3934 int64_t frb_val = get_d_register(frb);
3935 set_d_register(frt, frb_val);
3939 int bf =
instr->Bits(25, 23);
3940 int imm =
instr->Bits(15, 12);
3941 int fp_condition_mask = 0xF0000000 >> (bf * 4);
3942 fp_condition_reg_ &= ~fp_condition_mask;
3943 fp_condition_reg_ |= (imm << (28 - (bf * 4)));
3944 if (
instr->Bit(0)) {
3945 condition_reg_ &= 0xF0FFFFFF;
3946 condition_reg_ |= (imm << 23);
3951 int frb =
instr->RBValue();
3952 int64_t frb_dval = get_d_register(frb);
3954 int l =
instr->Bits(25, 25);
3956 fp_condition_reg_ = frb_ival;
3960 if (
instr->Bit(0)) {
3968 int frt =
instr->RTValue();
3969 int64_t lval =
static_cast<int64_t
>(fp_condition_reg_);
3970 set_d_register(frt, lval);
3974 int bf =
instr->Bits(25, 23);
3975 int bfa =
instr->Bits(20, 18);
3976 int cr_shift = (7 - bf) *
CRWIDTH;
3977 int fp_shift = (7 - bfa) *
CRWIDTH;
3978 int field_val = (fp_condition_reg_ >> fp_shift) & 0xF;
3979 condition_reg_ &= ~(0x0F << cr_shift);
3980 condition_reg_ |= (field_val << cr_shift);
3994 int bt =
instr->Bits(25, 21);
3996 if (
instr->Bit(0)) {
4002 int bt =
instr->Bits(25, 21);
4004 if (
instr->Bit(0)) {
4010 int frt =
instr->RTValue();
4011 int frb =
instr->RBValue();
4012 double frb_val = get_double_from_d_register(frb);
4013 double frt_val = std::fabs(frb_val);
4014 set_d_register_from_double(frt, frt_val);
4018 int ra =
instr->RAValue();
4019 int rs =
instr->RSValue();
4020 uintptr_t rs_val = get_register(rs);
4021 int sh = (
instr->Bits(15, 11) | (
instr->Bit(1) << 5));
4022 int mb = (
instr->Bits(10, 6) | (
instr->Bit(5) << 5));
4023 DCHECK(sh >= 0 && sh <= 63);
4024 DCHECK(mb >= 0 && mb <= 63);
4025 uintptr_t
result = base::bits::RotateLeft64(rs_val, sh);
4026 uintptr_t
mask = 0xFFFFFFFFFFFFFFFF >> mb;
4028 set_register(ra,
result);
4029 if (
instr->Bit(0)) {
4035 int ra =
instr->RAValue();
4036 int rs =
instr->RSValue();
4037 uintptr_t rs_val = get_register(rs);
4038 int sh = (
instr->Bits(15, 11) | (
instr->Bit(1) << 5));
4039 int me = (
instr->Bits(10, 6) | (
instr->Bit(5) << 5));
4040 DCHECK(sh >= 0 && sh <= 63);
4041 DCHECK(me >= 0 && me <= 63);
4042 uintptr_t
result = base::bits::RotateLeft64(rs_val, sh);
4043 uintptr_t
mask = 0xFFFFFFFFFFFFFFFF << (63 - me);
4045 set_register(ra,
result);
4046 if (
instr->Bit(0)) {
4052 int ra =
instr->RAValue();
4053 int rs =
instr->RSValue();
4054 uintptr_t rs_val = get_register(rs);
4055 int sh = (
instr->Bits(15, 11) | (
instr->Bit(1) << 5));
4056 int mb = (
instr->Bits(10, 6) | (
instr->Bit(5) << 5));
4057 DCHECK(sh >= 0 && sh <= 63);
4058 DCHECK(mb >= 0 && mb <= 63);
4059 uintptr_t
result = base::bits::RotateLeft64(rs_val, sh);
4060 uintptr_t
mask = (0xFFFFFFFFFFFFFFFF >> mb) & (0xFFFFFFFFFFFFFFFF << sh);
4062 set_register(ra,
result);
4063 if (
instr->Bit(0)) {
4069 int ra =
instr->RAValue();
4070 int rs =
instr->RSValue();
4071 uintptr_t rs_val = get_register(rs);
4072 intptr_t ra_val = get_register(ra);
4073 int sh = (
instr->Bits(15, 11) | (
instr->Bit(1) << 5));
4074 int mb = (
instr->Bits(10, 6) | (
instr->Bit(5) << 5));
4076 uintptr_t
result = base::bits::RotateLeft64(rs_val, sh);
4079 uintptr_t bit = 0x8000000000000000 >> mb;
4080 for (; mb <= me; mb++) {
4084 }
else if (mb == me + 1) {
4085 mask = 0xFFFFFFFFFFFFFFFF;
4087 uintptr_t bit = 0x8000000000000000 >> (me + 1);
4088 mask = 0xFFFFFFFFFFFFFFFF;
4089 for (; me < mb; me++) {
4097 set_register(ra,
result);
4098 if (
instr->Bit(0)) {
4104 int ra =
instr->RAValue();
4105 int rs =
instr->RSValue();
4106 int rb =
instr->RBValue();
4107 uintptr_t rs_val = get_register(rs);
4108 uintptr_t rb_val = get_register(rb);
4109 int sh = (rb_val & 0x3F);
4110 int mb = (
instr->Bits(10, 6) | (
instr->Bit(5) << 5));
4111 DCHECK(sh >= 0 && sh <= 63);
4112 DCHECK(mb >= 0 && mb <= 63);
4113 uintptr_t
result = base::bits::RotateLeft64(rs_val, sh);
4114 uintptr_t
mask = 0xFFFFFFFFFFFFFFFF >> mb;
4116 set_register(ra,
result);
4117 if (
instr->Bit(0)) {
4126 int ra =
instr->RAValue();
4127 int rt =
instr->RTValue();
4128 int64_t ra_val = ra == 0 ? 0 : get_register(ra);
4130 switch (
instr->Bits(1, 0)) {
4133 set_register(rt,
result);
4138 set_register(rt,
result);
4140 set_register(ra, ra_val +
offset);
4145 set_register(rt,
result);
4154 int ra =
instr->RAValue();
4155 int rs =
instr->RSValue();
4156 int64_t ra_val = ra == 0 ? 0 : get_register(ra);
4157 int64_t rs_val = get_register(rs);
4159 WriteDW(ra_val +
offset, rs_val);
4160 if (opcode == STDU) {
4162 set_register(ra, ra_val +
offset);
4167 int frt =
instr->RTValue();
4168 int fra =
instr->RAValue();
4169 int frb =
instr->RBValue();
4170 double fra_val = get_double_from_d_register(fra);
4171 double frb_val = get_double_from_d_register(frb);
4172 double frt_val = fra_val + frb_val;
4173 set_d_register_from_double(frt, frt_val);
4177 int frt =
instr->RTValue();
4178 int fra =
instr->RAValue();
4179 int frb =
instr->RBValue();
4180 double fra_val = get_double_from_d_register(fra);
4181 double frb_val = get_double_from_d_register(frb);
4182 double frt_val = fra_val - frb_val;
4183 set_d_register_from_double(frt, frt_val);
4187 int frt =
instr->RTValue();
4188 int fra =
instr->RAValue();
4189 int frb =
instr->RBValue();
4190 double fra_val = get_double_from_d_register(fra);
4191 double frb_val = get_double_from_d_register(frb);
4192 double frt_val = fra_val * frb_val;
4193 set_d_register_from_double(frt, frt_val);
4197 int frt =
instr->RTValue();
4198 int fra =
instr->RAValue();
4199 int frb =
instr->RBValue();
4200 double fra_val = get_double_from_d_register(fra);
4201 double frb_val = get_double_from_d_register(frb);
4202 double frt_val = fra_val / frb_val;
4203 set_d_register_from_double(frt, frt_val);
4207 int rs =
instr->RSValue();
4208 uint32_t rs_val =
static_cast<int32_t>(get_register(rs));
4209 uint8_t fxm =
instr->Bits(19, 12);
4210 uint8_t bit_mask = 0x80;
4211 const int field_bit_count = 4;
4212 const int max_field_index = 7;
4214 for (
int i = 0;
i <= max_field_index;
i++) {
4215 result <<= field_bit_count;
4216 uint32_t source = condition_reg_;
4217 if ((bit_mask & fxm) != 0) {
4222 (max_field_index -
i) * field_bit_count;
4230 DECODE_VX_INSTRUCTION(vrt, ra, rb, T)
4231 GET_ADDRESS(ra, rb, ra_val, rb_val)
4232 intptr_t addr = (ra_val + rb_val) & 0xFFFFFFFFFFFFFFF0;
4233 simdr_t* ptr =
reinterpret_cast<simdr_t*
>(addr);
4234 set_simd_register(vrt, *ptr);
4238 DECODE_VX_INSTRUCTION(vrs, ra, rb, S)
4239 GET_ADDRESS(ra, rb, ra_val, rb_val)
4240 __int128 vrs_val = base::bit_cast<__int128>(get_simd_register(vrs).int8);
4241 WriteQW((ra_val + rb_val) & 0xFFFFFFFFFFFFFFF0, vrs_val);
4245 DECODE_VX_INSTRUCTION(xt, ra, rb, T)
4246 GET_ADDRESS(ra, rb, ra_val, rb_val)
4247 set_simd_register_by_lane<int64_t>(xt, 0, ReadDW(ra_val + rb_val));
4248 set_simd_register_by_lane<int64_t>(
4249 xt, 1, ReadDW(ra_val + rb_val + kSystemPointerSize));
4253 DECODE_VX_INSTRUCTION(vrt, ra, rb, T)
4254 GET_ADDRESS(ra, rb, ra_val, rb_val)
4255 intptr_t addr = ra_val + rb_val;
4256 simdr_t* ptr =
reinterpret_cast<simdr_t*
>(addr);
4257 set_simd_register(vrt, *ptr);
4261 DECODE_VX_INSTRUCTION(xs, ra, rb, S)
4262 GET_ADDRESS(ra, rb, ra_val, rb_val)
4263 WriteDW(ra_val + rb_val, get_simd_register_by_lane<int64_t>(xs, 0));
4264 WriteDW(ra_val + rb_val + kSystemPointerSize,
4265 get_simd_register_by_lane<int64_t>(xs, 1));
4269 DECODE_VX_INSTRUCTION(vrs, ra, rb, S)
4270 GET_ADDRESS(ra, rb, ra_val, rb_val)
4271 intptr_t addr = ra_val + rb_val;
4272 __int128 vrs_val = base::bit_cast<__int128>(get_simd_register(vrs).int8);
4273 WriteQW(addr, vrs_val);
4277 DECODE_VX_INSTRUCTION(xt, ra, rb, T)
4278 GET_ADDRESS(ra, rb, ra_val, rb_val)
4279 set_simd_register_by_lane<uint64_t>(xt, 0, ReadBU(ra_val + rb_val));
4283 DECODE_VX_INSTRUCTION(xt, ra, rb, T)
4284 GET_ADDRESS(ra, rb, ra_val, rb_val)
4285 set_simd_register_by_lane<uint64_t>(xt, 0, ReadHU(ra_val + rb_val));
4289 DECODE_VX_INSTRUCTION(xt, ra, rb, T)
4290 GET_ADDRESS(ra, rb, ra_val, rb_val)
4291 set_simd_register_by_lane<uint64_t>(xt, 0, ReadWU(ra_val + rb_val));
4295 DECODE_VX_INSTRUCTION(xt, ra, rb, T)
4296 GET_ADDRESS(ra, rb, ra_val, rb_val)
4297 set_simd_register_by_lane<int64_t>(xt, 0, ReadDW(ra_val + rb_val));
4301 DECODE_VX_INSTRUCTION(xs, ra, rb, S)
4302 GET_ADDRESS(ra, rb, ra_val, rb_val)
4303 WriteB(ra_val + rb_val, get_simd_register_by_lane<int8_t>(xs, 7));
4307 DECODE_VX_INSTRUCTION(xs, ra, rb, S)
4308 GET_ADDRESS(ra, rb, ra_val, rb_val)
4309 WriteH(ra_val + rb_val, get_simd_register_by_lane<int16_t>(xs, 3));
4313 DECODE_VX_INSTRUCTION(xs, ra, rb, S)
4314 GET_ADDRESS(ra, rb, ra_val, rb_val)
4315 WriteW(ra_val + rb_val, get_simd_register_by_lane<int32_t>(xs, 1));
4319 DECODE_VX_INSTRUCTION(xs, ra, rb, S)
4320 GET_ADDRESS(ra, rb, ra_val, rb_val)
4321 WriteDW(ra_val + rb_val, get_simd_register_by_lane<int64_t>(xs, 0));
4325 int t =
instr->RTValue();
4326 int b =
instr->RBValue();
4327 __int128 xb_val = base::bit_cast<__int128>(get_simd_register(b).int8);
4328 __int128 xb_val_reversed = __builtin_bswap128(xb_val);
4329 simdr_t simdr_xb = base::bit_cast<simdr_t>(xb_val_reversed);
4330 set_simd_register(t, simdr_xb);
4333#define VSPLT(type) \
4334 uint8_t uim = instr->Bits(19, 16); \
4335 int vrt = instr->RTValue(); \
4336 int vrb = instr->RBValue(); \
4337 type value = get_simd_register_by_lane<type>(vrb, uim); \
4338 FOR_EACH_LANE(i, type) { set_simd_register_by_lane<type>(vrt, i, value); }
4352 int8_t imm8 =
instr->Bits(18, 11);
4353 int t =
instr->RTValue();
4354 FOR_EACH_LANE(
i, int8_t) {
4355 set_simd_register_by_lane<int8_t>(t,
i, imm8);
4360#define VSPLTI(type) \
4361 type sim = static_cast<type>(SIGN_EXT_IMM5(instr->Bits(20, 16))); \
4362 int vrt = instr->RTValue(); \
4363 FOR_EACH_LANE(i, type) { set_simd_register_by_lane<type>(vrt, i, sim); }
4377#define VINSERT(type, element) \
4378 uint8_t uim = instr->Bits(19, 16); \
4379 int vrt = instr->RTValue(); \
4380 int vrb = instr->RBValue(); \
4381 set_simd_register_bytes<type>( \
4382 vrt, uim, get_simd_register_by_lane<type>(vrb, element));
4400#define VINSERT_IMMEDIATE(type) \
4401 uint8_t uim = instr->Bits(19, 16); \
4402 int vrt = instr->RTValue(); \
4403 int rb = instr->RBValue(); \
4404 type src = static_cast<type>(get_register(rb)); \
4405 set_simd_register_bytes<type>(vrt, uim, src);
4407 VINSERT_IMMEDIATE(int64_t)
4411 VINSERT_IMMEDIATE(int32_t)
4414#undef VINSERT_IMMEDIATE
4415#define VEXTRACT(type, element) \
4416 uint8_t uim = instr->Bits(19, 16); \
4417 int vrt = instr->RTValue(); \
4418 int vrb = instr->RBValue(); \
4419 type val = get_simd_register_bytes<type>(vrb, uim); \
4420 set_simd_register_by_lane<uint64_t>(vrt, 0, 0); \
4421 set_simd_register_by_lane<uint64_t>(vrt, 1, 0); \
4422 set_simd_register_by_lane<type>(vrt, element, val);
4424 VEXTRACT(uint64_t, 0)
4428 VEXTRACT(uint32_t, 1)
4432 VEXTRACT(uint16_t, 3)
4436 VEXTRACT(uint8_t, 7)
4440#define VECTOR_LOGICAL_OP(expr) \
4441 DECODE_VX_INSTRUCTION(t, a, b, T) \
4442 FOR_EACH_LANE(i, int64_t) { \
4443 int64_t a_val = get_simd_register_by_lane<int64_t>(a, i); \
4444 int64_t b_val = get_simd_register_by_lane<int64_t>(b, i); \
4445 set_simd_register_by_lane<int64_t>(t, i, expr); \
4448 VECTOR_LOGICAL_OP(a_val & b_val)
4452 VECTOR_LOGICAL_OP(a_val & (~b_val))
4456 VECTOR_LOGICAL_OP(a_val | b_val)
4460 VECTOR_LOGICAL_OP(~(a_val | b_val))
4464 VECTOR_LOGICAL_OP(a_val ^ b_val)
4467#undef VECTOR_LOGICAL_OP
4468#define VECTOR_ARITHMETIC_OP(type, op) \
4469 DECODE_VX_INSTRUCTION(t, a, b, T) \
4470 FOR_EACH_LANE(i, type) { \
4471 set_simd_register_by_lane<type>( \
4473 get_simd_register_by_lane<type>(a, i) \
4474 op get_simd_register_by_lane<type>(b, i)); \
4477 VECTOR_ARITHMETIC_OP(
double, +)
4481 VECTOR_ARITHMETIC_OP(
double, -)
4485 VECTOR_ARITHMETIC_OP(
double, *)
4489 VECTOR_ARITHMETIC_OP(
double, /)
4493 VECTOR_ARITHMETIC_OP(
float, +)
4497 VECTOR_ARITHMETIC_OP(
float, -)
4501 VECTOR_ARITHMETIC_OP(
float, *)
4505 VECTOR_ARITHMETIC_OP(
float, /)
4509 VECTOR_ARITHMETIC_OP(int64_t, +)
4513 VECTOR_ARITHMETIC_OP(int64_t, -)
4517 VECTOR_ARITHMETIC_OP(int64_t, *)
4521 VECTOR_ARITHMETIC_OP(int32_t, +)
4525 VECTOR_ARITHMETIC_OP(int32_t, -)
4529 VECTOR_ARITHMETIC_OP(int32_t, *)
4533 VECTOR_ARITHMETIC_OP(int16_t, +)
4537 VECTOR_ARITHMETIC_OP(int16_t, -)
4541 VECTOR_ARITHMETIC_OP(int8_t, +)
4545 VECTOR_ARITHMETIC_OP(int8_t, -)
4548#define VECTOR_MULTIPLY_EVEN_ODD(input_type, result_type, is_odd) \
4549 DECODE_VX_INSTRUCTION(t, a, b, T) \
4550 size_t i = 0, j = 0, k = 0; \
4551 size_t lane_size = sizeof(input_type); \
4556 for (; j < kSimd128Size; i += 2, j += lane_size * 2, k++) { \
4557 result_type src0 = \
4558 static_cast<result_type>(get_simd_register_by_lane<input_type>(a, i)); \
4559 result_type src1 = \
4560 static_cast<result_type>(get_simd_register_by_lane<input_type>(b, i)); \
4561 set_simd_register_by_lane<result_type>(t, k, src0 * src1); \
4564 VECTOR_MULTIPLY_EVEN_ODD(uint8_t, uint16_t,
false)
4568 VECTOR_MULTIPLY_EVEN_ODD(int8_t, int16_t,
false)
4572 VECTOR_MULTIPLY_EVEN_ODD(uint8_t, uint16_t,
true)
4576 VECTOR_MULTIPLY_EVEN_ODD(int8_t, int16_t,
true)
4580 VECTOR_MULTIPLY_EVEN_ODD(uint16_t, uint32_t,
false)
4584 VECTOR_MULTIPLY_EVEN_ODD(int16_t, int32_t,
false)
4588 VECTOR_MULTIPLY_EVEN_ODD(uint16_t, uint32_t,
true)
4592 VECTOR_MULTIPLY_EVEN_ODD(int16_t, int32_t,
true)
4596 VECTOR_MULTIPLY_EVEN_ODD(uint32_t, uint64_t,
false)
4600 VECTOR_MULTIPLY_EVEN_ODD(int32_t, int64_t,
false)
4604 VECTOR_MULTIPLY_EVEN_ODD(uint32_t, uint64_t,
true)
4608 VECTOR_MULTIPLY_EVEN_ODD(int32_t, int64_t,
true)
4611#undef VECTOR_MULTIPLY_EVEN_ODD
4612#define VECTOR_MERGE(type, is_low_side) \
4613 DECODE_VX_INSTRUCTION(t, a, b, T) \
4614 constexpr size_t index_limit = (kSimd128Size / sizeof(type)) / 2; \
4615 for (size_t i = 0, source_index = is_low_side ? i + index_limit : i; \
4616 i < index_limit; i++, source_index++) { \
4617 set_simd_register_by_lane<type>( \
4618 t, 2 * i, get_simd_register_by_lane<type>(a, source_index)); \
4619 set_simd_register_by_lane<type>( \
4620 t, (2 * i) + 1, get_simd_register_by_lane<type>(b, source_index)); \
4623 VECTOR_MERGE(int32_t,
true)
4627 VECTOR_MERGE(int32_t,
false)
4631 VECTOR_MERGE(int16_t,
true)
4635 VECTOR_MERGE(int16_t,
false)
4639#undef VECTOR_ARITHMETIC_OP
4640#define VECTOR_MIN_MAX_OP(type, op) \
4641 DECODE_VX_INSTRUCTION(t, a, b, T) \
4642 FOR_EACH_LANE(i, type) { \
4643 type a_val = get_simd_register_by_lane<type>(a, i); \
4644 type b_val = get_simd_register_by_lane<type>(b, i); \
4645 set_simd_register_by_lane<type>(t, i, a_val op b_val ? a_val : b_val); \
4648 DECODE_VX_INSTRUCTION(t, a, b, T)
4649 double a_val = get_double_from_d_register(a);
4650 double b_val = get_double_from_d_register(b);
4651 set_d_register_from_double(t, VSXFPMin<double>(a_val, b_val));
4655 DECODE_VX_INSTRUCTION(t, a, b, T)
4656 double a_val = get_double_from_d_register(a);
4657 double b_val = get_double_from_d_register(b);
4658 set_d_register_from_double(t, VSXFPMax<double>(a_val, b_val));
4662 DECODE_VX_INSTRUCTION(t, a, b, T)
4663 FOR_EACH_LANE(
i,
double) {
4664 double a_val = get_simd_register_by_lane<double>(a,
i);
4665 double b_val = get_simd_register_by_lane<double>(b,
i);
4666 set_simd_register_by_lane<double>(t,
i, VSXFPMin<double>(a_val, b_val));
4671 DECODE_VX_INSTRUCTION(t, a, b, T)
4672 FOR_EACH_LANE(
i,
double) {
4673 double a_val = get_simd_register_by_lane<double>(a,
i);
4674 double b_val = get_simd_register_by_lane<double>(b,
i);
4675 set_simd_register_by_lane<double>(t,
i, VSXFPMax<double>(a_val, b_val));
4680 DECODE_VX_INSTRUCTION(t, a, b, T)
4681 FOR_EACH_LANE(
i,
float) {
4682 float a_val = get_simd_register_by_lane<float>(a,
i);
4683 float b_val = get_simd_register_by_lane<float>(b,
i);
4684 set_simd_register_by_lane<float>(t,
i, VMXFPMin(a_val, b_val));
4689 DECODE_VX_INSTRUCTION(t, a, b, T)
4690 FOR_EACH_LANE(
i,
float) {
4691 float a_val = get_simd_register_by_lane<float>(a,
i);
4692 float b_val = get_simd_register_by_lane<float>(b,
i);
4693 set_simd_register_by_lane<float>(t,
i, VMXFPMax(a_val, b_val));
4698 VECTOR_MIN_MAX_OP(int64_t, <)
4702 VECTOR_MIN_MAX_OP(uint64_t, <)
4706 VECTOR_MIN_MAX_OP(int32_t, <)
4710 VECTOR_MIN_MAX_OP(uint32_t, <)
4714 VECTOR_MIN_MAX_OP(int16_t, <)
4718 VECTOR_MIN_MAX_OP(uint16_t, <)
4722 VECTOR_MIN_MAX_OP(int8_t, <)
4726 VECTOR_MIN_MAX_OP(uint8_t, <)
4730 VECTOR_MIN_MAX_OP(int64_t, >)
4734 VECTOR_MIN_MAX_OP(uint64_t, >)
4738 VECTOR_MIN_MAX_OP(int32_t, >)
4742 VECTOR_MIN_MAX_OP(uint32_t, >)
4746 VECTOR_MIN_MAX_OP(int16_t, >)
4750 VECTOR_MIN_MAX_OP(uint16_t, >)
4754 VECTOR_MIN_MAX_OP(int8_t, >)
4758 VECTOR_MIN_MAX_OP(uint8_t, >)
4761#undef VECTOR_MIN_MAX_OP
4762#define VECTOR_SHIFT_OP(type, op, mask) \
4763 DECODE_VX_INSTRUCTION(t, a, b, T) \
4764 FOR_EACH_LANE(i, type) { \
4765 set_simd_register_by_lane<type>( \
4767 get_simd_register_by_lane<type>(a, i) \
4768 op(get_simd_register_by_lane<type>(b, i) & mask)); \
4771 VECTOR_SHIFT_OP(int64_t, <<, 0x3f)
4775 VECTOR_SHIFT_OP(int64_t, >>, 0x3f)
4779 VECTOR_SHIFT_OP(uint64_t, >>, 0x3f)
4783 VECTOR_SHIFT_OP(int32_t, <<, 0x1f)
4787 VECTOR_SHIFT_OP(int32_t, >>, 0x1f)
4791 VECTOR_SHIFT_OP(uint32_t, >>, 0x1f)
4795 VECTOR_SHIFT_OP(int16_t, <<, 0xf)
4799 VECTOR_SHIFT_OP(int16_t, >>, 0xf)
4803 VECTOR_SHIFT_OP(uint16_t, >>, 0xf)
4807 VECTOR_SHIFT_OP(int8_t, <<, 0x7)
4811 VECTOR_SHIFT_OP(int8_t, >>, 0x7)
4815 VECTOR_SHIFT_OP(uint8_t, >>, 0x7)
4818#undef VECTOR_SHIFT_OP
4819#define VECTOR_COMPARE_OP(type_in, type_out, is_fp, op) \
4820 VectorCompareOp<type_in, type_out>( \
4821 this, instr, is_fp, [](type_in a, type_in b) { return a op b; });
4823 VECTOR_COMPARE_OP(
double, int64_t,
true, ==)
4827 VECTOR_COMPARE_OP(
double, int64_t,
true, >=)
4831 VECTOR_COMPARE_OP(
double, int64_t,
true, >)
4835 VECTOR_COMPARE_OP(
float, int32_t,
true, ==)
4839 VECTOR_COMPARE_OP(
float, int32_t,
true, >=)
4843 VECTOR_COMPARE_OP(
float, int32_t,
true, >)
4847 VECTOR_COMPARE_OP(uint64_t, int64_t,
false, ==)
4851 VECTOR_COMPARE_OP(int64_t, int64_t,
false, >)
4855 VECTOR_COMPARE_OP(uint64_t, int64_t,
false, >)
4859 VECTOR_COMPARE_OP(uint32_t, int32_t,
false, ==)
4863 VECTOR_COMPARE_OP(int32_t, int32_t,
false, >)
4867 VECTOR_COMPARE_OP(uint32_t, int32_t,
false, >)
4871 VECTOR_COMPARE_OP(uint16_t, int16_t,
false, ==)
4875 VECTOR_COMPARE_OP(int16_t, int16_t,
false, >)
4879 VECTOR_COMPARE_OP(uint16_t, int16_t,
false, >)
4883 VECTOR_COMPARE_OP(uint8_t, int8_t,
false, ==)
4887 VECTOR_COMPARE_OP(int8_t, int8_t,
false, >)
4891 VECTOR_COMPARE_OP(uint8_t, int8_t,
false, >)
4894#undef VECTOR_COMPARE_OP
4896 VectorConverFromFPSaturate<float, int32_t>(
this,
instr, kMinInt, kMaxInt);
4900 VectorConverFromFPSaturate<float, uint32_t>(
this,
instr, 0, kMaxUInt32);
4904 VectorConverFromFPSaturate<double, int32_t>(
this,
instr, kMinInt, kMaxInt,
4909 VectorConverFromFPSaturate<double, uint32_t>(
this,
instr, 0, kMaxUInt32,
4914 int t =
instr->RTValue();
4915 int b =
instr->RBValue();
4916 FOR_EACH_LANE(
i, int32_t) {
4917 int32_t b_val = get_simd_register_by_lane<int32_t>(b,
i);
4918 set_simd_register_by_lane<float>(t,
i,
static_cast<float>(b_val));
4923 int t =
instr->RTValue();
4924 int b =
instr->RBValue();
4925 FOR_EACH_LANE(
i, uint32_t) {
4926 uint32_t b_val = get_simd_register_by_lane<uint32_t>(b,
i);
4927 set_simd_register_by_lane<float>(t,
i,
static_cast<float>(b_val));
4932 int t =
instr->RTValue();
4933 int b =
instr->RBValue();
4934 FOR_EACH_LANE(
i, int64_t) {
4935 int64_t b_val = get_simd_register_by_lane<int64_t>(b,
i);
4936 set_simd_register_by_lane<double>(t,
i,
static_cast<double>(b_val));
4941 int t =
instr->RTValue();
4942 int b =
instr->RBValue();
4943 FOR_EACH_LANE(
i, uint64_t) {
4944 uint64_t b_val = get_simd_register_by_lane<uint64_t>(b,
i);
4945 set_simd_register_by_lane<double>(t,
i,
static_cast<double>(b_val));
4950 int t =
instr->RTValue();
4951 int b =
instr->RBValue();
4952 FOR_EACH_LANE(
i,
double) {
4953 float b_val = get_simd_register_by_lane<float>(b, 2 *
i);
4954 set_simd_register_by_lane<double>(t,
i,
static_cast<double>(b_val));
4959 int t =
instr->RTValue();
4960 int b =
instr->RBValue();
4961 FOR_EACH_LANE(
i,
double) {
4962 double b_val = get_simd_register_by_lane<double>(b,
i);
4963 set_simd_register_by_lane<float>(t, 2 *
i,
static_cast<float>(b_val));
4968 int t =
instr->RTValue();
4969 int b =
instr->RBValue();
4970 uint64_t double_bits = get_d_register(b);
4972 float f = base::bit_cast<float, uint32_t>(
4973 static_cast<uint32_t
>(double_bits >> 32));
4974 double_bits = base::bit_cast<uint64_t, double>(
static_cast<double>(f));
4977 double_bits &= 0xFFF7FFFFFFFFFFFFU;
4979 set_d_register(t, double_bits);
4983 int t =
instr->RTValue();
4984 int b =
instr->RBValue();
4985 double b_val = get_double_from_d_register(b);
4986 uint64_t float_bits =
static_cast<uint64_t
>(
4987 base::bit_cast<uint32_t, float>(
static_cast<float>(b_val)));
4989 if (is_snan(b_val)) {
4990 float_bits &= 0xFFBFFFFFU;
4993 float_bits = (float_bits << 32) | float_bits;
4994 set_d_register(t, float_bits);
4997#define VECTOR_UNPACK(S, D, if_high_side) \
4998 int t = instr->RTValue(); \
4999 int b = instr->RBValue(); \
5000 constexpr size_t kItemCount = kSimd128Size / sizeof(D); \
5001 D temps[kItemCount] = {0}; \
5003 FOR_EACH_LANE(i, D) { \
5004 temps[i] = get_simd_register_by_lane<S>(b, i, if_high_side); \
5006 FOR_EACH_LANE(i, D) { \
5007 set_simd_register_by_lane<D>(t, i, temps[i], if_high_side); \
5010 VECTOR_UNPACK(int8_t, int16_t,
true)
5014 VECTOR_UNPACK(int16_t, int32_t,
true)
5018 VECTOR_UNPACK(int32_t, int64_t,
true)
5022 VECTOR_UNPACK(int8_t, int16_t,
false)
5026 VECTOR_UNPACK(int16_t, int32_t,
false)
5030 VECTOR_UNPACK(int32_t, int64_t,
false)
5035 VectorPackSaturate<int32_t, int16_t>(
this,
instr, kMinInt16, kMaxInt16);
5039 VectorPackSaturate<int32_t, uint16_t>(
this,
instr, 0, kMaxUInt16);
5043 VectorPackSaturate<int16_t, int8_t>(
this,
instr, kMinInt8, kMaxInt8);
5047 VectorPackSaturate<int16_t, uint8_t>(
this,
instr, 0, kMaxUInt8);
5050#define VECTOR_ADD_SUB_SATURATE(intermediate_type, result_type, op, min_val, \
5052 DECODE_VX_INSTRUCTION(t, a, b, T) \
5053 FOR_EACH_LANE(i, result_type) { \
5054 intermediate_type a_val = static_cast<intermediate_type>( \
5055 get_simd_register_by_lane<result_type>(a, i)); \
5056 intermediate_type b_val = static_cast<intermediate_type>( \
5057 get_simd_register_by_lane<result_type>(b, i)); \
5058 intermediate_type t_val = a_val op b_val; \
5059 if (t_val > max_val) \
5061 else if (t_val < min_val) \
5063 set_simd_register_by_lane<result_type>(t, i, \
5064 static_cast<result_type>(t_val)); \
5067 VECTOR_ADD_SUB_SATURATE(int32_t, int16_t, +, kMinInt16, kMaxInt16)
5071 VECTOR_ADD_SUB_SATURATE(int32_t, int16_t, -, kMinInt16, kMaxInt16)
5075 VECTOR_ADD_SUB_SATURATE(int32_t, uint16_t, +, 0, kMaxUInt16)
5079 VECTOR_ADD_SUB_SATURATE(int32_t, uint16_t, -, 0, kMaxUInt16)
5083 VECTOR_ADD_SUB_SATURATE(int16_t, int8_t, +, kMinInt8, kMaxInt8)
5087 VECTOR_ADD_SUB_SATURATE(int16_t, int8_t, -, kMinInt8, kMaxInt8)
5091 VECTOR_ADD_SUB_SATURATE(int16_t, uint8_t, +, 0, kMaxUInt8)
5095 VECTOR_ADD_SUB_SATURATE(int16_t, uint8_t, -, 0, kMaxUInt8)
5098#undef VECTOR_ADD_SUB_SATURATE
5099#define VECTOR_FP_ROUNDING(type, op) \
5100 int t = instr->RTValue(); \
5101 int b = instr->RBValue(); \
5102 FOR_EACH_LANE(i, type) { \
5103 type b_val = get_simd_register_by_lane<type>(b, i); \
5104 set_simd_register_by_lane<type>(t, i, std::op(b_val)); \
5107 VECTOR_FP_ROUNDING(
double, ceil)
5111 VECTOR_FP_ROUNDING(
double, floor)
5115 VECTOR_FP_ROUNDING(
double, trunc)
5119 VECTOR_FP_ROUNDING(
double, nearbyint)
5123 VECTOR_FP_ROUNDING(
float, ceilf)
5127 VECTOR_FP_ROUNDING(
float, floorf)
5131 VECTOR_FP_ROUNDING(
float, truncf)
5135 VECTOR_FP_ROUNDING(
float, nearbyintf)
5138#undef VECTOR_FP_ROUNDING
5140 int vrt =
instr->RTValue();
5141 int vra =
instr->RAValue();
5142 int vrb =
instr->RBValue();
5143 int vrc =
instr->RCValue();
5144 unsigned __int128 src_1 =
5145 base::bit_cast<__int128>(get_simd_register(vra).int8);
5146 unsigned __int128 src_2 =
5147 base::bit_cast<__int128>(get_simd_register(vrb).int8);
5148 unsigned __int128 src_3 =
5149 base::bit_cast<__int128>(get_simd_register(vrc).int8);
5150 unsigned __int128 tmp = (src_1 & ~src_3) | (src_2 & src_3);
5151 simdr_t*
result =
reinterpret_cast<simdr_t*
>(&
tmp);
5152 set_simd_register(vrt, *
result);
5156 int vrt =
instr->RTValue();
5157 int vra =
instr->RAValue();
5158 int vrb =
instr->RBValue();
5159 int vrc =
instr->RCValue();
5161 FOR_EACH_LANE(
i, int8_t) {
5162 int8_t lane_num = get_simd_register_by_lane<int8_t>(vrc,
i);
5164 lane_num = (lane_num << 3) >> 3;
5166 if (lane_num >= kSimd128Size) {
5170 temp[
i] = get_simd_register_by_lane<int8_t>(
reg, lane_num);
5172 FOR_EACH_LANE(
i, int8_t) {
5173 set_simd_register_by_lane<int8_t>(vrt,
i, temp[
i]);
5178 DECODE_VX_INSTRUCTION(t, a, b, T)
5180 unsigned __int128 src_bits =
5181 base::bit_cast<__int128>(get_simd_register(a).int8);
5184 uint8_t selected_bit_index = get_simd_register_by_lane<uint8_t>(b,
i);
5185 if (selected_bit_index < (kSimd128Size * kBitsPerByte)) {
5186 unsigned __int128 bit_value = (src_bits << selected_bit_index) >>
5188 result_bits |= bit_value;
5191 set_simd_register_by_lane<uint64_t>(t, 0, 0);
5192 set_simd_register_by_lane<uint64_t>(t, 1, 0);
5193 set_simd_register_by_lane<uint16_t>(t, 3, result_bits);
5196#define VECTOR_FP_QF(type, sign, function) \
5197 DECODE_VX_INSTRUCTION(t, a, b, T) \
5198 FOR_EACH_LANE(i, type) { \
5199 type a_val = get_simd_register_by_lane<type>(a, i); \
5200 type b_val = get_simd_register_by_lane<type>(b, i); \
5201 type t_val = get_simd_register_by_lane<type>(t, i); \
5202 type reuslt = sign * function(a_val, t_val, (sign * b_val)); \
5203 if (isinf(a_val)) reuslt = a_val; \
5204 if (isinf(b_val)) reuslt = b_val; \
5205 if (isinf(t_val)) reuslt = t_val; \
5206 set_simd_register_by_lane<type>(t, i, reuslt); \
5209 VECTOR_FP_QF(
double, +1, fma)
5213 VECTOR_FP_QF(
double, -1, fma)
5217 VECTOR_FP_QF(
float, +1, fmaf)
5221 VECTOR_FP_QF(
float, -1, fmaf)
5226 int vrt =
instr->RTValue();
5227 int vra =
instr->RAValue();
5228 int vrb =
instr->RBValue();
5229 int vrc =
instr->RCValue();
5230 FOR_EACH_LANE(
i, int16_t) {
5231 int16_t vra_val = get_simd_register_by_lane<int16_t>(vra,
i);
5232 int16_t vrb_val = get_simd_register_by_lane<int16_t>(vrb,
i);
5233 int16_t vrc_val = get_simd_register_by_lane<int16_t>(vrc,
i);
5234 int32_t temp = vra_val * vrb_val;
5235 temp = (temp + 0x00004000) >> 15;
5237 if (temp > kMaxInt16)
5239 else if (temp < kMinInt16)
5241 set_simd_register_by_lane<int16_t>(vrt,
i,
static_cast<int16_t>(temp));
5246 int vrt =
instr->RTValue();
5247 int vra =
instr->RAValue();
5248 int vrb =
instr->RBValue();
5249 int vrc =
instr->RCValue();
5250 FOR_EACH_LANE(
i, int32_t) {
5251 int8_t vra_1_val = get_simd_register_by_lane<int8_t>(vra, 4 *
i),
5252 vra_2_val = get_simd_register_by_lane<int8_t>(vra, (4 *
i) + 1),
5253 vra_3_val = get_simd_register_by_lane<int8_t>(vra, (4 *
i) + 2),
5254 vra_4_val = get_simd_register_by_lane<int8_t>(vra, (4 *
i) + 3);
5255 uint8_t vrb_1_val = get_simd_register_by_lane<uint8_t>(vrb, 4 *
i),
5257 get_simd_register_by_lane<uint8_t>(vrb, (4 *
i) + 1),
5259 get_simd_register_by_lane<uint8_t>(vrb, (4 *
i) + 2),
5261 get_simd_register_by_lane<uint8_t>(vrb, (4 *
i) + 3);
5262 int32_t vrc_val = get_simd_register_by_lane<int32_t>(vrc,
i);
5263 int32_t temp1 = vra_1_val * vrb_1_val, temp2 = vra_2_val * vrb_2_val,
5264 temp3 = vra_3_val * vrb_3_val, temp4 = vra_4_val * vrb_4_val;
5265 temp1 = temp1 + temp2 + temp3 + temp4 + vrc_val;
5266 set_simd_register_by_lane<int32_t>(vrt,
i, temp1);
5271 int vrt =
instr->RTValue();
5272 int vra =
instr->RAValue();
5273 int vrb =
instr->RBValue();
5274 int vrc =
instr->RCValue();
5275 FOR_EACH_LANE(
i, int32_t) {
5276 int16_t vra_1_val = get_simd_register_by_lane<int16_t>(vra, 2 *
i);
5278 get_simd_register_by_lane<int16_t>(vra, (2 *
i) + 1);
5279 int16_t vrb_1_val = get_simd_register_by_lane<int16_t>(vrb, 2 *
i);
5281 get_simd_register_by_lane<int16_t>(vrb, (2 *
i) + 1);
5282 int32_t vrc_val = get_simd_register_by_lane<int32_t>(vrc,
i);
5283 int32_t temp1 = vra_1_val * vrb_1_val, temp2 = vra_2_val * vrb_2_val;
5284 temp1 = temp1 + temp2 + vrc_val;
5285 set_simd_register_by_lane<int32_t>(vrt,
i, temp1);
5290 int vrt =
instr->RTValue();
5291 int vra =
instr->RAValue();
5292 int vrb =
instr->RBValue();
5293 int vrc =
instr->RCValue();
5294 FOR_EACH_LANE(
i, uint16_t) {
5295 uint16_t vra_val = get_simd_register_by_lane<uint16_t>(vra,
i);
5296 uint16_t vrb_val = get_simd_register_by_lane<uint16_t>(vrb,
i);
5297 uint16_t vrc_val = get_simd_register_by_lane<uint16_t>(vrc,
i);
5298 set_simd_register_by_lane<uint16_t>(vrt,
i,
5299 (vra_val * vrb_val) + vrc_val);
5303#define VECTOR_UNARY_OP(type, op) \
5304 int t = instr->RTValue(); \
5305 int b = instr->RBValue(); \
5306 FOR_EACH_LANE(i, type) { \
5307 set_simd_register_by_lane<type>( \
5308 t, i, op(get_simd_register_by_lane<type>(b, i))); \
5311 VECTOR_UNARY_OP(
double, std::abs)
5315 VECTOR_UNARY_OP(
double, -)
5319 VECTOR_UNARY_OP(
double, std::sqrt)
5323 VECTOR_UNARY_OP(
float, std::abs)
5327 VECTOR_UNARY_OP(
float, -)
5331 VECTOR_UNARY_OP(
float, std::sqrt)
5335 VECTOR_UNARY_OP(
float, base::Recip)
5339 VECTOR_UNARY_OP(
float, base::RecipSqrt)
5343 VECTOR_UNARY_OP(int32_t, -)
5347 VECTOR_UNARY_OP(int64_t, -)
5350#undef VECTOR_UNARY_OP
5351#define VECTOR_ROUNDING_AVERAGE(intermediate_type, result_type) \
5352 DECODE_VX_INSTRUCTION(t, a, b, T) \
5353 FOR_EACH_LANE(i, result_type) { \
5354 intermediate_type a_val = static_cast<intermediate_type>( \
5355 get_simd_register_by_lane<result_type>(a, i)); \
5356 intermediate_type b_val = static_cast<intermediate_type>( \
5357 get_simd_register_by_lane<result_type>(b, i)); \
5358 intermediate_type t_val = ((a_val + b_val) + 1) >> 1; \
5359 set_simd_register_by_lane<result_type>(t, i, \
5360 static_cast<result_type>(t_val)); \
5363 VECTOR_ROUNDING_AVERAGE(uint32_t, uint16_t)
5367 VECTOR_ROUNDING_AVERAGE(uint16_t, uint8_t)
5370#undef VECTOR_ROUNDING_AVERAGE
5372 int t =
instr->RTValue();
5373 int b =
instr->RBValue();
5374 FOR_EACH_LANE(
i, uint8_t) {
5375 set_simd_register_by_lane<uint8_t>(
5377 base::bits::CountPopulation(
5378 get_simd_register_by_lane<uint8_t>(b,
i)));
5382#define EXTRACT_MASK(type) \
5383 int rt = instr->RTValue(); \
5384 int vrb = instr->RBValue(); \
5385 uint64_t result = 0; \
5386 FOR_EACH_LANE(i, type) { \
5387 if (i > 0) result <<= 1; \
5388 result |= std::signbit(get_simd_register_by_lane<type>(vrb, i)); \
5390 set_register(rt, result);
5392 EXTRACT_MASK(int64_t)
5396 EXTRACT_MASK(int32_t)
5400 EXTRACT_MASK(int16_t)
5404 EXTRACT_MASK(int8_t)
5409#undef DECODE_VX_INSTRUCTION
5417void Simulator::Trace(Instruction*
instr) {
5422 dasm.InstructionDecode(buffer,
reinterpret_cast<uint8_t*
>(
instr));
5424 reinterpret_cast<intptr_t
>(
instr), buffer.
begin());
5428void Simulator::ExecuteInstruction(Instruction*
instr) {
5430 CheckICache(i_cache(),
instr);
5432 pc_modified_ =
false;
5433 if (InstructionTracingEnabled()) {
5436 uint32_t opcode =
instr->OpcodeField();
5437 if (opcode == TWI) {
5438 SoftwareInterrupt(
instr);
5440 ExecuteGeneric(
instr);
5442 if (!pc_modified_) {
5443 set_pc(
reinterpret_cast<intptr_t
>(
instr) + kInstrSize);
5447void Simulator::Execute() {
5450 intptr_t program_counter = get_pc();
5455 while (program_counter != end_sim_pc) {
5456 Instruction*
instr =
reinterpret_cast<Instruction*
>(program_counter);
5458 ExecuteInstruction(
instr);
5459 program_counter = get_pc();
5464 while (program_counter != end_sim_pc) {
5465 Instruction*
instr =
reinterpret_cast<Instruction*
>(program_counter);
5467 if (icount_ ==
v8_flags.stop_sim_at) {
5468 PPCDebugger dbg(
this);
5471 ExecuteInstruction(
instr);
5473 program_counter = get_pc();
5478void Simulator::CallInternal(Address entry) {
5480 isolate_->stack_guard()->AdjustStackLimitForSimulator();
5485 set_pc(*(
reinterpret_cast<intptr_t*
>(entry)));
5488 set_pc(
static_cast<intptr_t
>(entry));
5493 set_register(r12, get_pc());
5499 special_reg_lr_ = end_sim_pc;
5502 intptr_t r2_val = get_register(r2);
5503 intptr_t r13_val = get_register(r13);
5504 intptr_t r14_val = get_register(r14);
5505 intptr_t r15_val = get_register(r15);
5506 intptr_t r16_val = get_register(r16);
5507 intptr_t r17_val = get_register(r17);
5508 intptr_t r18_val = get_register(r18);
5509 intptr_t r19_val = get_register(r19);
5510 intptr_t r20_val = get_register(r20);
5511 intptr_t r21_val = get_register(r21);
5512 intptr_t r22_val = get_register(r22);
5513 intptr_t r23_val = get_register(r23);
5514 intptr_t r24_val = get_register(r24);
5515 intptr_t r25_val = get_register(r25);
5516 intptr_t r26_val = get_register(r26);
5517 intptr_t r27_val = get_register(r27);
5518 intptr_t r28_val = get_register(r28);
5519 intptr_t r29_val = get_register(r29);
5520 intptr_t r30_val = get_register(r30);
5521 intptr_t r31_val = get_register(fp);
5525 intptr_t callee_saved_value = icount_;
5526 set_register(r2, callee_saved_value);
5527 set_register(r13, callee_saved_value);
5528 set_register(r14, callee_saved_value);
5529 set_register(r15, callee_saved_value);
5530 set_register(r16, callee_saved_value);
5531 set_register(r17, callee_saved_value);
5532 set_register(r18, callee_saved_value);
5533 set_register(r19, callee_saved_value);
5534 set_register(r20, callee_saved_value);
5535 set_register(r21, callee_saved_value);
5536 set_register(r22, callee_saved_value);
5537 set_register(r23, callee_saved_value);
5538 set_register(r24, callee_saved_value);
5539 set_register(r25, callee_saved_value);
5540 set_register(r26, callee_saved_value);
5541 set_register(r27, callee_saved_value);
5542 set_register(r28, callee_saved_value);
5543 set_register(r29, callee_saved_value);
5544 set_register(r30, callee_saved_value);
5545 set_register(fp, callee_saved_value);
5552 CHECK_EQ(callee_saved_value, get_register(r2));
5555 CHECK_EQ(callee_saved_value, get_register(r13));
5557 CHECK_EQ(callee_saved_value, get_register(r14));
5558 CHECK_EQ(callee_saved_value, get_register(r15));
5559 CHECK_EQ(callee_saved_value, get_register(r16));
5560 CHECK_EQ(callee_saved_value, get_register(r17));
5561 CHECK_EQ(callee_saved_value, get_register(r18));
5562 CHECK_EQ(callee_saved_value, get_register(r19));
5563 CHECK_EQ(callee_saved_value, get_register(r20));
5564 CHECK_EQ(callee_saved_value, get_register(r21));
5565 CHECK_EQ(callee_saved_value, get_register(r22));
5566 CHECK_EQ(callee_saved_value, get_register(r23));
5567 CHECK_EQ(callee_saved_value, get_register(r24));
5568 CHECK_EQ(callee_saved_value, get_register(r25));
5569 CHECK_EQ(callee_saved_value, get_register(r26));
5570 CHECK_EQ(callee_saved_value, get_register(r27));
5571 CHECK_EQ(callee_saved_value, get_register(r28));
5572 CHECK_EQ(callee_saved_value, get_register(r29));
5573 CHECK_EQ(callee_saved_value, get_register(r30));
5574 CHECK_EQ(callee_saved_value, get_register(fp));
5577 set_register(r2, r2_val);
5578 set_register(r13, r13_val);
5579 set_register(r14, r14_val);
5580 set_register(r15, r15_val);
5581 set_register(r16, r16_val);
5582 set_register(r17, r17_val);
5583 set_register(r18, r18_val);
5584 set_register(r19, r19_val);
5585 set_register(r20, r20_val);
5586 set_register(r21, r21_val);
5587 set_register(r22, r22_val);
5588 set_register(r23, r23_val);
5589 set_register(r24, r24_val);
5590 set_register(r25, r25_val);
5591 set_register(r26, r26_val);
5592 set_register(r27, r27_val);
5593 set_register(r28, r28_val);
5594 set_register(r29, r29_val);
5595 set_register(r30, r30_val);
5596 set_register(fp, r31_val);
5599intptr_t Simulator::CallImpl(Address entry,
int argument_count,
5600 const intptr_t* arguments) {
5604 int reg_arg_count = std::min(8, argument_count);
5605 int stack_arg_count = argument_count - reg_arg_count;
5606 for (
int i = 0;
i < reg_arg_count;
i++) {
5607 set_register(
i + 3, arguments[
i]);
5611 intptr_t original_stack = get_register(sp);
5613 intptr_t entry_stack =
5616 if (base::OS::ActivationFrameAlignment() != 0) {
5617 entry_stack &= -base::OS::ActivationFrameAlignment();
5621 intptr_t* stack_argument =
5622 reinterpret_cast<intptr_t*
>(entry_stack) + kStackFrameExtraParamSlot;
5623 memcpy(stack_argument, arguments + reg_arg_count,
5624 stack_arg_count *
sizeof(*arguments));
5625 set_register(sp, entry_stack);
5627 CallInternal(entry);
5630 CHECK_EQ(entry_stack, get_register(sp));
5631 set_register(sp, original_stack);
5633 return get_register(r3);
5636void Simulator::CallFP(Address entry,
double d0,
double d1) {
5637 set_d_register_from_double(1, d0);
5638 set_d_register_from_double(2, d1);
5639 CallInternal(entry);
5642int32_t Simulator::CallFPReturnsInt(Address entry,
double d0,
double d1) {
5643 CallFP(entry, d0, d1);
5648double Simulator::CallFPReturnsDouble(Address entry,
double d0,
double d1) {
5649 CallFP(entry, d0, d1);
5650 return get_double_from_d_register(1);
5653uintptr_t Simulator::PushAddress(uintptr_t address) {
5654 uintptr_t new_sp = get_register(sp) -
sizeof(uintptr_t);
5655 uintptr_t* stack_slot =
reinterpret_cast<uintptr_t*
>(new_sp);
5656 *stack_slot = address;
5657 set_register(sp, new_sp);
5661uintptr_t Simulator::PopAddress() {
5662 uintptr_t current_sp = get_register(sp);
5663 uintptr_t* stack_slot =
reinterpret_cast<uintptr_t*
>(current_sp);
5664 uintptr_t address = *stack_slot;
5665 set_register(sp, current_sp +
sizeof(uintptr_t));
5669void Simulator::GlobalMonitor::Clear() {
5670 access_state_ = MonitorAccess::Open;
5672 size_ = TransactionSize::None;
5673 thread_id_ = ThreadId::Invalid();
5676void Simulator::GlobalMonitor::NotifyLoadExcl(uintptr_t addr,
5677 TransactionSize size,
5678 ThreadId thread_id) {
5684 access_state_ = MonitorAccess::Exclusive;
5685 tagged_addr_ = addr;
5687 thread_id_ = thread_id;
5690void Simulator::GlobalMonitor::NotifyStore(uintptr_t addr, TransactionSize size,
5691 ThreadId thread_id) {
5692 if (access_state_ == MonitorAccess::Exclusive) {
5694 uintptr_t transaction_start = addr;
5695 uintptr_t transaction_end = addr +
static_cast<uintptr_t
>(
size);
5696 uintptr_t exclusive_transaction_start = tagged_addr_;
5697 uintptr_t exclusive_transaction_end =
5698 tagged_addr_ +
static_cast<uintptr_t
>(
size_);
5699 bool is_not_overlapped = transaction_end < exclusive_transaction_start ||
5700 exclusive_transaction_end < transaction_start;
5701 if (!is_not_overlapped && thread_id_ != thread_id) {
5707bool Simulator::GlobalMonitor::NotifyStoreExcl(uintptr_t addr,
5708 TransactionSize size,
5709 ThreadId thread_id) {
5710 bool permission = access_state_ == MonitorAccess::Exclusive &&
5711 addr == tagged_addr_ &&
size_ == size &&
5712 thread_id_ == thread_id;
virtual void VisitPointer(const void *address)=0
TemplateHashMapEntry< void *, void * > Entry
constexpr T * begin() const
static int Number(const char *name)
V8_EXPORT_PRIVATE void SetInstructionBits(Instr value, WritableJitAllocation *jit_allocation=nullptr)
static constexpr int8_t kNumRegisters
static constexpr DwVfpRegister from_code(int8_t code)
static constexpr Register from_code(int code)
static int Number(const char *name)
static constexpr int ToInt(const Tagged< Object > object)
#define SIGN_EXT_IMM16(imm)
#define ABI_RETURNS_OBJECT_PAIRS_IN_REGS
#define SIGN_EXT_IMM34(imm)
#define ABI_USES_FUNCTION_DESCRIPTORS
#define ABI_PASSES_HANDLES_IN_REGS
std::optional< TNode< JSArray > > a
ZoneVector< RpoNumber > & result
#define DEFINE_LAZY_LEAKY_OBJECT_GETTER(T, FunctionName,...)
InstructionOperand source
V8_INLINE Dest bit_cast(Source const &source)
CustomMatcherTemplateHashMapImpl< DefaultAllocationPolicy > CustomMatcherHashMap
void DeleteArray(T *array)
constexpr VFPRoundingMode kRoundToNearest
constexpr VFPRoundingMode kRoundToMinusInf
constexpr int kSimd128Size
constexpr int kBitsPerByte
const int kNumRequiredStackFrameSlots
constexpr BarrierOption LD
void PrintF(const char *format,...)
char * ReadLine(const char *prompt)
const Instr rtCallRedirInstr
constexpr FPDataProcessing2SourceOp FSUB
constexpr FPDataProcessing1SourceOp FABS
const int kStackFrameExtraParamSlot
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
constexpr SoftwareInterruptCodes kBreakpoint
void Print(Tagged< Object > obj)
constexpr VFPRoundingMode kRoundToPlusInf
constexpr int kSystemPointerSize
constexpr SoftwareInterruptCodes kCallRtRedirected
constexpr FPDataProcessing2SourceOp FDIV
const uint32_t kFPRoundingModeMask
void ShortPrint(Tagged< Object > obj, FILE *out)
constexpr int kNoRegister
constexpr FPDataProcessing2SourceOp FADD
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr uint32_t kMinUInt32
constexpr int kBitsPerSystemPointer
constexpr FPDataProcessing1SourceOp FNEG
constexpr VFPRoundingMode kRoundToZero
constexpr uint8_t kInstrSize
constexpr MiscInstructionsBits74 BX
constexpr FPDataProcessing2SourceOp FMUL
constexpr uint32_t kMaxUInt32
constexpr FPDataProcessing1SourceOp FSQRT
V8_WARN_UNUSED_RESULT bool IsValidHeapObject(Heap *heap, Tagged< HeapObject > object)
constexpr uint32_t kStopCodeMask
constexpr int kNumRegisters
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
base::SmallVector< RegisterT, kStaticCapacity > registers_
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_NE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
std::unique_ptr< ValueMirror > value