8#if defined(USE_SIMULATOR)
29#if V8_ENABLE_WEBASSEMBLY
37 Simulator::GlobalMonitor::Get)
42inline bool HaveSameSign(int64_t a, int64_t b) {
return ((a ^ b) >= 0); }
44uint32_t get_fcsr_condition_bit(uint32_t
cc) {
53inline void printf_instr(
const char* _Format, ...) {
55 va_start(varList, _Format);
56 vprintf(_Format, varList);
60#define printf_instr(...)
71class Loong64Debugger {
73 explicit Loong64Debugger(Simulator* sim) : sim_(sim) {}
75 void Stop(Instruction*
instr);
79 void PrintAllRegsIncludingFPU();
83 static const Instr kBreakpointInstr =
BREAK | 0xFFFF;
84 static const Instr kNopInstr = 0x0;
88 int64_t GetRegisterValue(
int regnum);
89 int64_t GetFPURegisterValue(
int regnum);
90 float GetFPURegisterValueFloat(
int regnum);
91 double GetFPURegisterValueDouble(
int regnum);
92 bool GetValue(
const char* desc, int64_t* value);
95 bool SetBreakpoint(Instruction* breakpc);
96 bool DeleteBreakpoint(Instruction* breakpc);
100 void UndoBreakpoints();
101 void RedoBreakpoints();
104inline void UNSUPPORTED() { printf(
"Sim: Unsupported instruction.\n"); }
106void Loong64Debugger::Stop(Instruction*
instr) {
109 PrintF(
"Simulator hit (%u)\n", code);
113int64_t Loong64Debugger::GetRegisterValue(
int regnum) {
115 return sim_->get_pc();
117 return sim_->get_register(regnum);
121int64_t Loong64Debugger::GetFPURegisterValue(
int regnum) {
123 return sim_->get_pc();
125 return sim_->get_fpu_register(regnum);
129float Loong64Debugger::GetFPURegisterValueFloat(
int regnum) {
131 return sim_->get_pc();
133 return sim_->get_fpu_register_float(regnum);
137double Loong64Debugger::GetFPURegisterValueDouble(
int regnum) {
139 return sim_->get_pc();
141 return sim_->get_fpu_register_double(regnum);
145bool Loong64Debugger::GetValue(
const char* desc, int64_t* value) {
150 *value = GetRegisterValue(regnum);
153 *value = GetFPURegisterValue(fpuregnum);
155 }
else if (strncmp(desc,
"0x", 2) == 0) {
156 return SScanF(desc + 2,
"%" SCNx64,
reinterpret_cast<uint64_t*
>(value)) ==
159 return SScanF(desc,
"%" SCNu64,
reinterpret_cast<uint64_t*
>(value)) == 1;
163bool Loong64Debugger::SetBreakpoint(Instruction* breakpc) {
165 if (sim_->break_pc_ !=
nullptr) {
170 sim_->break_pc_ = breakpc;
171 sim_->break_instr_ = breakpc->InstructionBits();
177bool Loong64Debugger::DeleteBreakpoint(Instruction* breakpc) {
178 if (sim_->break_pc_ !=
nullptr) {
179 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
182 sim_->break_pc_ =
nullptr;
183 sim_->break_instr_ = 0;
187void Loong64Debugger::UndoBreakpoints() {
188 if (sim_->break_pc_ !=
nullptr) {
189 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
193void Loong64Debugger::RedoBreakpoints() {
194 if (sim_->break_pc_ !=
nullptr) {
195 sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
199void Loong64Debugger::PrintAllRegs() {
200#define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)
204 PrintF(
"%3s: 0x%016" PRIx64
" %14" PRId64
"\t%3s: 0x%016" PRIx64
" %14" PRId64
205 "\t%3s: 0x%016" PRIx64
" %14" PRId64
"\n",
206 REG_INFO(1), REG_INFO(2), REG_INFO(4));
208 PrintF(
"%34s\t%3s: 0x%016" PRIx64
" %14" PRId64
" \t%3s: 0x%016" PRIx64
210 "", REG_INFO(3), REG_INFO(5));
212 PrintF(
"%34s\t%34s\t%3s: 0x%016" PRIx64
" %14" PRId64
" \n",
"",
"",
215 PrintF(
"%34s\t%34s\t%3s: 0x%016" PRIx64
" %14" PRId64
" \n",
"",
"",
219 for (
int i = 0;
i < 8;
i++) {
220 PrintF(
"%3s: 0x%016" PRIx64
" %14" PRId64
" \t%3s: 0x%016" PRIx64
222 REG_INFO(8 +
i), REG_INFO(16 +
i));
226 PrintF(
"%3s: 0x%016" PRIx64
" %14" PRId64
" \t%3s: 0x%016" PRIx64
227 " %14" PRId64
" \t%3s: 0x%016" PRIx64
" %14" PRId64
" \n",
228 REG_INFO(24), REG_INFO(26), REG_INFO(32));
230 PrintF(
"%3s: 0x%016" PRIx64
" %14" PRId64
" \t%3s: 0x%016" PRIx64
231 " %14" PRId64
" \t%3s: 0x%016" PRIx64
" %14" PRId64
" \n",
232 REG_INFO(25), REG_INFO(27), REG_INFO(33));
234 PrintF(
"%3s: 0x%016" PRIx64
" %14" PRId64
" \t%3s: 0x%016" PRIx64
235 " %14" PRId64
" \t%3s: 0x%016" PRIx64
" %14" PRId64
" \n",
236 REG_INFO(29), REG_INFO(30), REG_INFO(28));
238 PrintF(
"%3s: 0x%016" PRIx64
" %14" PRId64
" \t%3s: 0x%016" PRIx64
240 REG_INFO(31), REG_INFO(34));
245void Loong64Debugger::PrintAllRegsIncludingFPU() {
246#define FPU_REG_INFO(n) \
247 FPURegisters::Name(n), GetFPURegisterValue(n), GetFPURegisterValueDouble(n)
254 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(0));
255 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(1));
256 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(2));
257 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(3));
258 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(4));
259 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(5));
260 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(6));
261 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(7));
262 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(8));
263 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(9));
264 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(10));
265 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(11));
266 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(12));
267 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(13));
268 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(14));
269 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(15));
270 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(16));
271 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(17));
272 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(18));
273 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(19));
274 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(20));
275 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(21));
276 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(22));
277 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(23));
278 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(24));
279 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(25));
280 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(26));
281 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(27));
282 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(28));
283 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(29));
284 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(30));
285 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n", FPU_REG_INFO(31));
290void Loong64Debugger::Debug() {
291 if (
v8_flags.correctness_fuzzer_suppressions) {
292 PrintF(
"Debugger disabled for differential fuzzing.\n");
295 intptr_t last_pc = -1;
298#define COMMAND_SIZE 63
302#define XSTR(a) STR(a)
304 char cmd[COMMAND_SIZE + 1];
305 char arg1[ARG_SIZE + 1];
306 char arg2[ARG_SIZE + 1];
307 char* argv[3] = {cmd, arg1, arg2};
310 cmd[COMMAND_SIZE] = 0;
318 while (!done && (sim_->get_pc() != Simulator::end_sim_pc)) {
319 if (last_pc != sim_->get_pc()) {
324 dasm.InstructionDecode(buffer,
325 reinterpret_cast<uint8_t*
>(sim_->get_pc()));
326 PrintF(
" 0x%016" PRIx64
" %s\n", sim_->get_pc(), buffer.
begin());
327 last_pc = sim_->get_pc();
330 if (line ==
nullptr) {
333 char* last_input = sim_->last_debugger_input();
334 if (strcmp(line,
"\n") == 0 && last_input !=
nullptr) {
338 sim_->set_last_debugger_input(line);
342 int argc = SScanF(line,
343 "%" XSTR(COMMAND_SIZE)
"s "
344 "%" XSTR(ARG_SIZE)
"s "
345 "%" XSTR(ARG_SIZE)
"s",
347 if ((strcmp(cmd,
"si") == 0) || (strcmp(cmd,
"stepi") == 0)) {
348 Instruction*
instr =
reinterpret_cast<Instruction*
>(sim_->get_pc());
351 sim_->InstructionDecode(
352 reinterpret_cast<Instruction*
>(sim_->get_pc()));
355 PrintF(
"/!\\ Jumping over generated breakpoint.\n");
358 }
else if ((strcmp(cmd,
"c") == 0) || (strcmp(cmd,
"cont") == 0)) {
360 sim_->InstructionDecode(
reinterpret_cast<Instruction*
>(sim_->get_pc()));
363 }
else if ((strcmp(cmd,
"p") == 0) || (strcmp(cmd,
"print") == 0)) {
367 if (strcmp(arg1,
"all") == 0) {
369 }
else if (strcmp(arg1,
"allf") == 0) {
370 PrintAllRegsIncludingFPU();
376 value = GetRegisterValue(regnum);
377 PrintF(
"%s: 0x%08" PRIx64
" %" PRId64
" \n", arg1, value,
380 value = GetFPURegisterValue(fpuregnum);
381 dvalue = GetFPURegisterValueDouble(fpuregnum);
382 PrintF(
"%3s: 0x%016" PRIx64
" %16.4e\n",
385 PrintF(
"%s unrecognized\n", arg1);
390 if (strcmp(arg2,
"single") == 0) {
396 value = GetFPURegisterValue(fpuregnum);
397 value &= 0xFFFFFFFFUL;
398 fvalue = GetFPURegisterValueFloat(fpuregnum);
399 PrintF(
"%s: 0x%08" PRIx64
" %11.4e\n", arg1, value, fvalue);
401 PrintF(
"%s unrecognized\n", arg1);
404 PrintF(
"print <fpu register> single\n");
407 PrintF(
"print <register> or print <fpu register> single\n");
410 }
else if ((strcmp(cmd,
"po") == 0) ||
411 (strcmp(cmd,
"printobject") == 0)) {
415 if (GetValue(arg1, &value)) {
417 os << arg1 <<
": \n";
422 os << Brief(obj) <<
"\n";
425 os << arg1 <<
" unrecognized\n";
428 PrintF(
"printobject <value>\n");
430 }
else if (strcmp(cmd,
"stack") == 0 || strcmp(cmd,
"mem") == 0 ||
431 strcmp(cmd,
"dump") == 0) {
432 int64_t* cur =
nullptr;
433 int64_t*
end =
nullptr;
436 if (strcmp(cmd,
"stack") == 0) {
437 cur =
reinterpret_cast<int64_t*
>(sim_->get_register(Simulator::sp));
440 if (!GetValue(arg1, &value)) {
441 PrintF(
"%s unrecognized\n", arg1);
444 cur =
reinterpret_cast<int64_t*
>(
value);
449 if (argc == next_arg) {
452 if (!GetValue(argv[next_arg], &words)) {
458 bool skip_obj_print = (strcmp(cmd,
"dump") == 0);
460 PrintF(
" 0x%012" PRIxPTR
" : 0x%016" PRIx64
" %14" PRId64
" ",
461 reinterpret_cast<intptr_t
>(cur), *cur, *cur);
463 Heap* current_heap = sim_->isolate_->heap();
464 if (!skip_obj_print) {
480 }
else if ((strcmp(cmd,
"disasm") == 0) || (strcmp(cmd,
"dpc") == 0) ||
481 (strcmp(cmd,
"di") == 0)) {
487 uint8_t* cur =
nullptr;
488 uint8_t*
end =
nullptr;
491 cur =
reinterpret_cast<uint8_t*
>(sim_->get_pc());
493 }
else if (argc == 2) {
498 if (GetValue(arg1, &value)) {
499 cur =
reinterpret_cast<uint8_t*
>(
value);
506 if (GetValue(arg1, &value)) {
507 cur =
reinterpret_cast<uint8_t*
>(sim_->get_pc());
515 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
516 cur =
reinterpret_cast<uint8_t*
>(value1);
522 dasm.InstructionDecode(buffer, cur);
523 PrintF(
" 0x%08" PRIxPTR
" %s\n",
reinterpret_cast<intptr_t
>(cur),
527 }
else if (strcmp(cmd,
"gdb") == 0) {
528 PrintF(
"relinquishing control to gdb\n");
530 PrintF(
"regaining control from gdb\n");
531 }
else if (strcmp(cmd,
"break") == 0) {
534 if (GetValue(arg1, &value)) {
535 if (!SetBreakpoint(
reinterpret_cast<Instruction*
>(value))) {
536 PrintF(
"setting breakpoint failed\n");
539 PrintF(
"%s unrecognized\n", arg1);
542 PrintF(
"break <address>\n");
544 }
else if (strcmp(cmd,
"del") == 0) {
545 if (!DeleteBreakpoint(
nullptr)) {
546 PrintF(
"deleting breakpoint failed\n");
548 }
else if (strcmp(cmd,
"flags") == 0) {
549 PrintF(
"No flags on LOONG64 !\n");
550 }
else if (strcmp(cmd,
"stop") == 0) {
552 intptr_t stop_pc = sim_->get_pc() - 2 *
kInstrSize;
553 Instruction* stop_instr =
reinterpret_cast<Instruction*
>(stop_pc);
554 Instruction* msg_address =
555 reinterpret_cast<Instruction*
>(stop_pc +
kInstrSize);
556 if ((argc == 2) && (strcmp(arg1,
"unstop") == 0)) {
558 if (sim_->IsStopInstruction(stop_instr)) {
559 stop_instr->SetInstructionBits(kNopInstr);
560 msg_address->SetInstructionBits(kNopInstr);
562 PrintF(
"Not at debugger stop.\n");
564 }
else if (argc == 3) {
566 if (strcmp(arg1,
"info") == 0) {
567 if (strcmp(arg2,
"all") == 0) {
568 PrintF(
"Stop information:\n");
571 sim_->PrintStopInfo(
i);
573 }
else if (GetValue(arg2, &value)) {
574 sim_->PrintStopInfo(value);
576 PrintF(
"Unrecognized argument.\n");
578 }
else if (strcmp(arg1,
"enable") == 0) {
580 if (strcmp(arg2,
"all") == 0) {
585 }
else if (GetValue(arg2, &value)) {
586 sim_->EnableStop(value);
588 PrintF(
"Unrecognized argument.\n");
590 }
else if (strcmp(arg1,
"disable") == 0) {
592 if (strcmp(arg2,
"all") == 0) {
595 sim_->DisableStop(
i);
597 }
else if (GetValue(arg2, &value)) {
598 sim_->DisableStop(value);
600 PrintF(
"Unrecognized argument.\n");
604 PrintF(
"Wrong usage. Use help command for more information.\n");
606 }
else if ((strcmp(cmd,
"stat") == 0) || (strcmp(cmd,
"st") == 0)) {
616 uint8_t* cur =
nullptr;
617 uint8_t*
end =
nullptr;
620 cur =
reinterpret_cast<uint8_t*
>(sim_->get_pc());
622 }
else if (argc == 2) {
624 if (GetValue(arg1, &value)) {
625 cur =
reinterpret_cast<uint8_t*
>(
value);
632 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
633 cur =
reinterpret_cast<uint8_t*
>(value1);
639 dasm.InstructionDecode(buffer, cur);
640 PrintF(
" 0x%08" PRIxPTR
" %s\n",
reinterpret_cast<intptr_t
>(cur),
644 }
else if ((strcmp(cmd,
"h") == 0) || (strcmp(cmd,
"help") == 0)) {
646 PrintF(
" continue execution (alias 'c')\n");
648 PrintF(
" step one instruction (alias 'si')\n");
649 PrintF(
"print <register>\n");
650 PrintF(
" print register content (alias 'p')\n");
651 PrintF(
" use register name 'all' to print all registers\n");
652 PrintF(
"printobject <register>\n");
653 PrintF(
" print an object from a register (alias 'po')\n");
654 PrintF(
"stack [<words>]\n");
655 PrintF(
" dump stack content, default dump 10 words)\n");
656 PrintF(
"mem <address> [<words>]\n");
657 PrintF(
" dump memory content, default dump 10 words)\n");
658 PrintF(
"dump [<words>]\n");
660 " dump memory content without pretty printing JS objects, default "
664 PrintF(
"disasm [<instructions>]\n");
665 PrintF(
"disasm [<address/register>]\n");
666 PrintF(
"disasm [[<address/register>] <instructions>]\n");
667 PrintF(
" disassemble code, default is 10 instructions\n");
668 PrintF(
" from pc (alias 'di')\n");
671 PrintF(
"break <address>\n");
672 PrintF(
" set a break point on the address\n");
674 PrintF(
" delete the breakpoint\n");
675 PrintF(
"stop feature:\n");
676 PrintF(
" Description:\n");
677 PrintF(
" Stops are debug instructions inserted by\n");
678 PrintF(
" the Assembler::stop() function.\n");
679 PrintF(
" When hitting a stop, the Simulator will\n");
680 PrintF(
" stop and give control to the Debugger.\n");
681 PrintF(
" All stop codes are watched:\n");
682 PrintF(
" - They can be enabled / disabled: the Simulator\n");
683 PrintF(
" will / won't stop when hitting them.\n");
684 PrintF(
" - The Simulator keeps track of how many times they \n");
685 PrintF(
" are met. (See the info command.) Going over a\n");
686 PrintF(
" disabled stop still increases its counter. \n");
688 PrintF(
" stop info all/<code> : print infos about number <code>\n");
689 PrintF(
" or all stop(s).\n");
690 PrintF(
" stop enable/disable all/<code> : enables / disables\n");
691 PrintF(
" all or number <code> stop(s)\n");
693 PrintF(
" ignore the stop instruction at the current location\n");
696 PrintF(
"Unknown command: %s\n", cmd);
712bool Simulator::ICacheMatch(
void*
one,
void* two) {
713 DCHECK_EQ(
reinterpret_cast<intptr_t
>(
one) & CachePage::kPageMask, 0);
714 DCHECK_EQ(
reinterpret_cast<intptr_t
>(two) & CachePage::kPageMask, 0);
718static uint32_t ICacheHash(
void*
key) {
719 return static_cast<uint32_t
>(
reinterpret_cast<uintptr_t
>(
key)) >> 2;
722static bool AllOnOnePage(uintptr_t
start,
size_t size) {
723 intptr_t start_page = (
start & ~CachePage::kPageMask);
724 intptr_t end_page = ((
start +
size) & ~CachePage::kPageMask);
725 return start_page == end_page;
728void Simulator::set_last_debugger_input(
char* input) {
730 last_debugger_input_ = input;
733void Simulator::SetRedirectInstruction(Instruction* instruction) {
738 void* start_addr,
size_t size) {
739 int64_t
start =
reinterpret_cast<int64_t
>(start_addr);
740 int64_t intra_line = (
start & CachePage::kLineMask);
743 size = ((size - 1) | CachePage::kLineMask) + 1;
745 while (!AllOnOnePage(
start, size - 1)) {
746 int bytes_to_flush = CachePage::kPageSize -
offset;
747 FlushOnePage(i_cache,
start, bytes_to_flush);
748 start += bytes_to_flush;
749 size -= bytes_to_flush;
754 FlushOnePage(i_cache,
start, size);
761 if (entry->value ==
nullptr) {
762 CachePage* new_page =
new CachePage();
763 entry->value = new_page;
765 return reinterpret_cast<CachePage*
>(entry->value);
770 intptr_t
start,
size_t size) {
774 DCHECK_EQ(size & CachePage::kLineMask, 0);
775 void* page =
reinterpret_cast<void*
>(
start & (~CachePage::kPageMask));
777 CachePage* cache_page = GetCachePage(i_cache, page);
778 char* valid_bytemap = cache_page->ValidityByte(
offset);
779 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
783 Instruction*
instr) {
784 int64_t address =
reinterpret_cast<int64_t
>(
instr);
785 void* page =
reinterpret_cast<void*
>(address & (~CachePage::kPageMask));
786 void* line =
reinterpret_cast<void*
>(address & (~CachePage::kLineMask));
787 int offset = (address & CachePage::kPageMask);
788 CachePage* cache_page = GetCachePage(i_cache, page);
789 char* cache_valid_byte = cache_page->ValidityByte(
offset);
790 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
791 char* cached_line = cache_page->CachedData(
offset & ~CachePage::kLineMask);
798 memcpy(cached_line, line, CachePage::kLineLength);
799 *cache_valid_byte = CachePage::LINE_VALID;
803Simulator::Simulator(Isolate* isolate) :
isolate_(isolate) {
806 size_t stack_size = AllocatedStackSize();
807 stack_ =
reinterpret_cast<uintptr_t
>(
new uint8_t[stack_size]);
809 pc_modified_ =
false;
821 FPUregisters_[
i] = 0;
823 for (
int i = 0;
i < kNumCFRegisters;
i++) {
838 last_debugger_input_ =
nullptr;
841Simulator::~Simulator() {
842 GlobalMonitor::Get()->RemoveLinkedAddress(&global_monitor_thread_);
843 delete[]
reinterpret_cast<uint8_t*
>(stack_);
847Simulator* Simulator::current(Isolate* isolate) {
849 isolate->FindOrAllocatePerThreadDataForThisThread();
852 Simulator* sim = isolate_data->simulator();
853 if (sim ==
nullptr) {
855 sim =
new Simulator(isolate);
856 isolate_data->set_simulator(sim);
861#define FloatPoint_Covert_F32(func) \
862 float Simulator::func(float value) { \
863 float result = std::func(value); \
864 if (std::isnan(result)) { \
865 uint32_t q_nan, nan; \
866 nan = *reinterpret_cast<uint32_t*>(&result); \
867 q_nan = nan | 0x400000; \
868 *reinterpret_cast<uint32_t*>(&result) = q_nan; \
872#define FloatPoint_Covert_F64(func) \
873 FloatPoint_Covert_F32(func) \
874 double Simulator::func(double value) { \
875 double result = std::func(value); \
876 if (std::isnan(result)) { \
877 uint64_t q_nan, nan; \
878 nan = *reinterpret_cast<uint64_t*>(&value); \
879 q_nan = nan | 0x8000000000000; \
880 *reinterpret_cast<uint64_t*>(&result) = q_nan; \
885FloatPoint_Covert_F64(ceil)
886FloatPoint_Covert_F64(floor)
887FloatPoint_Covert_F64(trunc)
888#undef FloatPoint_Covert_F32
889#undef FloatPoint_Covert_F64
893void Simulator::set_register(
int reg, int64_t value) {
903void Simulator::set_dw_register(
int reg,
const int* dbl) {
910void Simulator::set_fpu_register(
int fpureg, int64_t value) {
911 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
912 FPUregisters_[fpureg] =
value;
915void Simulator::set_fpu_register_word(
int fpureg, int32_t value) {
917 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
919 pword =
reinterpret_cast<int32_t*
>(&FPUregisters_[fpureg]);
924void Simulator::set_fpu_register_hi_word(
int fpureg, int32_t value) {
926 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
928 phiword = (
reinterpret_cast<int32_t*
>(&FPUregisters_[fpureg])) + 1;
933void Simulator::set_fpu_register_float(
int fpureg,
float value) {
934 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
935 memcpy(&FPUregisters_[fpureg], &value,
sizeof(value));
938void Simulator::set_fpu_register_double(
int fpureg,
double value) {
939 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
940 memcpy(&FPUregisters_[fpureg], &value,
sizeof(value));
943void Simulator::set_cf_register(
int cfreg,
bool value) {
944 DCHECK((cfreg >= 0) && (cfreg < kNumCFRegisters));
945 CFregisters_[cfreg] =
value;
950int64_t Simulator::get_register(
int reg)
const {
958double Simulator::get_double_from_register_pair(
int reg) {
967 memcpy(&dm_val, buffer,
sizeof(
registers_[0]));
971int64_t Simulator::get_fpu_register(
int fpureg)
const {
972 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
973 return FPUregisters_[fpureg];
976int32_t Simulator::get_fpu_register_word(
int fpureg)
const {
977 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
978 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xFFFFFFFF);
981int32_t Simulator::get_fpu_register_signed_word(
int fpureg)
const {
982 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
983 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xFFFFFFFF);
986int32_t Simulator::get_fpu_register_hi_word(
int fpureg)
const {
987 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
988 return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xFFFFFFFF);
991float Simulator::get_fpu_register_float(
int fpureg)
const {
992 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
993 return base::bit_cast<float>(get_fpu_register_word(fpureg));
996double Simulator::get_fpu_register_double(
int fpureg)
const {
997 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
998 return base::bit_cast<double>(FPUregisters_[fpureg]);
1001bool Simulator::get_cf_register(
int cfreg)
const {
1002 DCHECK((cfreg >= 0) && (cfreg < kNumCFRegisters));
1003 return CFregisters_[cfreg];
1009void Simulator::GetFpArgs(
double*
x,
double*
y, int32_t*
z) {
1010 const int fparg2 = f1;
1011 *
x = get_fpu_register_double(f0);
1012 *
y = get_fpu_register_double(fparg2);
1013 *
z =
static_cast<int32_t>(get_register(a2));
1017void Simulator::SetFpResult(
const double&
result) {
1018 set_fpu_register_double(0,
result);
1022void Simulator::set_fcsr_bit(uint32_t cc,
bool value) {
1026 FCSR_ &= ~(1 <<
cc);
1030bool Simulator::test_fcsr_bit(uint32_t cc) {
return FCSR_ & (1 <<
cc); }
1032void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) {
1036unsigned int Simulator::get_fcsr_rounding_mode() {
1042bool Simulator::set_fcsr_round_error(
double original,
double rounded) {
1044 double max_int32 = std::numeric_limits<int32_t>::max();
1045 double min_int32 = std::numeric_limits<int32_t>::min();
1046 set_fcsr_bit(kFCSRInvalidOpCauseBit,
false);
1047 set_fcsr_bit(kFCSRUnderflowCauseBit,
false);
1048 set_fcsr_bit(kFCSROverflowCauseBit,
false);
1049 set_fcsr_bit(kFCSRInexactCauseBit,
false);
1051 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1052 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1056 if (original != rounded) {
1057 set_fcsr_bit(kFCSRInexactCauseBit,
true);
1060 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
1061 set_fcsr_bit(kFCSRUnderflowCauseBit,
true);
1065 if (rounded > max_int32 || rounded < min_int32) {
1066 set_fcsr_bit(kFCSROverflowCauseBit,
true);
1068 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1077bool Simulator::set_fcsr_round64_error(
double original,
double rounded) {
1081 double max_int64 =
static_cast<double>(std::numeric_limits<int64_t>::max());
1082 double min_int64 = std::numeric_limits<int64_t>::min();
1083 set_fcsr_bit(kFCSRInvalidOpCauseBit,
false);
1084 set_fcsr_bit(kFCSRUnderflowCauseBit,
false);
1085 set_fcsr_bit(kFCSROverflowCauseBit,
false);
1086 set_fcsr_bit(kFCSRInexactCauseBit,
false);
1088 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1089 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1093 if (original != rounded) {
1094 set_fcsr_bit(kFCSRInexactCauseBit,
true);
1097 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
1098 set_fcsr_bit(kFCSRUnderflowCauseBit,
true);
1102 if (rounded >= max_int64 || rounded < min_int64) {
1103 set_fcsr_bit(kFCSROverflowCauseBit,
true);
1105 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1114bool Simulator::set_fcsr_round_error(
float original,
float rounded) {
1116 double max_int32 = std::numeric_limits<int32_t>::max();
1117 double min_int32 = std::numeric_limits<int32_t>::min();
1118 set_fcsr_bit(kFCSRInvalidOpCauseBit,
false);
1119 set_fcsr_bit(kFCSRUnderflowCauseBit,
false);
1120 set_fcsr_bit(kFCSROverflowCauseBit,
false);
1121 set_fcsr_bit(kFCSRInexactCauseBit,
false);
1123 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1124 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1128 if (original != rounded) {
1129 set_fcsr_bit(kFCSRInexactCauseBit,
true);
1132 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) {
1133 set_fcsr_bit(kFCSRUnderflowCauseBit,
true);
1137 if (rounded > max_int32 || rounded < min_int32) {
1138 set_fcsr_bit(kFCSROverflowCauseBit,
true);
1140 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1147void Simulator::set_fpu_register_word_invalid_result(
float original,
1149 double max_int32 = std::numeric_limits<int32_t>::max();
1150 double min_int32 = std::numeric_limits<int32_t>::min();
1151 if (std::isnan(original)) {
1152 set_fpu_register_word(fd_reg(), 0);
1153 }
else if (rounded > max_int32) {
1154 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1155 }
else if (rounded < min_int32) {
1156 set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
1162void Simulator::set_fpu_register_invalid_result(
float original,
float rounded) {
1163 double max_int32 = std::numeric_limits<int32_t>::max();
1164 double min_int32 = std::numeric_limits<int32_t>::min();
1165 if (std::isnan(original)) {
1166 set_fpu_register(fd_reg(), 0);
1167 }
else if (rounded > max_int32) {
1168 set_fpu_register(fd_reg(), kFPUInvalidResult);
1169 }
else if (rounded < min_int32) {
1170 set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
1176void Simulator::set_fpu_register_invalid_result64(
float original,
1180 double max_int64 =
static_cast<double>(std::numeric_limits<int64_t>::max());
1181 double min_int64 = std::numeric_limits<int64_t>::min();
1182 if (std::isnan(original)) {
1183 set_fpu_register(fd_reg(), 0);
1184 }
else if (rounded >= max_int64) {
1185 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1186 }
else if (rounded < min_int64) {
1187 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
1193void Simulator::set_fpu_register_word_invalid_result(
double original,
1195 double max_int32 = std::numeric_limits<int32_t>::max();
1196 double min_int32 = std::numeric_limits<int32_t>::min();
1197 if (std::isnan(original)) {
1198 set_fpu_register_word(fd_reg(), 0);
1199 }
else if (rounded > max_int32) {
1200 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1201 }
else if (rounded < min_int32) {
1202 set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
1208void Simulator::set_fpu_register_invalid_result(
double original,
1210 double max_int32 = std::numeric_limits<int32_t>::max();
1211 double min_int32 = std::numeric_limits<int32_t>::min();
1212 if (std::isnan(original)) {
1213 set_fpu_register(fd_reg(), 0);
1214 }
else if (rounded > max_int32) {
1215 set_fpu_register(fd_reg(), kFPUInvalidResult);
1216 }
else if (rounded < min_int32) {
1217 set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
1223void Simulator::set_fpu_register_invalid_result64(
double original,
1227 double max_int64 =
static_cast<double>(std::numeric_limits<int64_t>::max());
1228 double min_int64 = std::numeric_limits<int64_t>::min();
1229 if (std::isnan(original)) {
1230 set_fpu_register(fd_reg(), 0);
1231 }
else if (rounded >= max_int64) {
1232 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1233 }
else if (rounded < min_int64) {
1234 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
1242bool Simulator::set_fcsr_round64_error(
float original,
float rounded) {
1246 double max_int64 =
static_cast<double>(std::numeric_limits<int64_t>::max());
1247 double min_int64 = std::numeric_limits<int64_t>::min();
1248 set_fcsr_bit(kFCSRInvalidOpCauseBit,
false);
1249 set_fcsr_bit(kFCSRUnderflowCauseBit,
false);
1250 set_fcsr_bit(kFCSROverflowCauseBit,
false);
1251 set_fcsr_bit(kFCSRInexactCauseBit,
false);
1253 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1254 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1258 if (original != rounded) {
1259 set_fcsr_bit(kFCSRInexactCauseBit,
true);
1262 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) {
1263 set_fcsr_bit(kFCSRUnderflowCauseBit,
true);
1267 if (rounded >= max_int64 || rounded < min_int64) {
1268 set_fcsr_bit(kFCSROverflowCauseBit,
true);
1270 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
1278void Simulator::round_according_to_fcsr(
double toRound,
double* rounded,
1279 int32_t* rounded_int) {
1294 switch (FCSR_ & kFPURoundingModeMask) {
1296 *rounded = floor(toRound + 0.5);
1297 *rounded_int =
static_cast<int32_t>(*rounded);
1298 if ((*rounded_int & 1) != 0 && *rounded_int - toRound == 0.5) {
1306 *rounded = trunc(toRound);
1307 *rounded_int =
static_cast<int32_t>(*rounded);
1310 *rounded = ceil(toRound);
1311 *rounded_int =
static_cast<int32_t>(*rounded);
1314 *rounded = floor(toRound);
1315 *rounded_int =
static_cast<int32_t>(*rounded);
1320void Simulator::round64_according_to_fcsr(
double toRound,
double* rounded,
1321 int64_t* rounded_int) {
1335 switch (FCSR_ & kFPURoundingModeMask) {
1337 *rounded = floor(toRound + 0.5);
1338 *rounded_int =
static_cast<int64_t
>(*rounded);
1339 if ((*rounded_int & 1) != 0 && *rounded_int - toRound == 0.5) {
1347 *rounded = trunc(toRound);
1348 *rounded_int =
static_cast<int64_t
>(*rounded);
1351 *rounded = ceil(toRound);
1352 *rounded_int =
static_cast<int64_t
>(*rounded);
1355 *rounded = floor(toRound);
1356 *rounded_int =
static_cast<int64_t
>(*rounded);
1361void Simulator::round_according_to_fcsr(
float toRound,
float* rounded,
1362 int32_t* rounded_int) {
1376 switch (FCSR_ & kFPURoundingModeMask) {
1378 *rounded = floor(toRound + 0.5);
1379 *rounded_int =
static_cast<int32_t>(*rounded);
1380 if ((*rounded_int & 1) != 0 && *rounded_int - toRound == 0.5) {
1388 *rounded = trunc(toRound);
1389 *rounded_int =
static_cast<int32_t>(*rounded);
1392 *rounded = ceil(toRound);
1393 *rounded_int =
static_cast<int32_t>(*rounded);
1396 *rounded = floor(toRound);
1397 *rounded_int =
static_cast<int32_t>(*rounded);
1402void Simulator::round64_according_to_fcsr(
float toRound,
float* rounded,
1403 int64_t* rounded_int) {
1417 switch (FCSR_ & kFPURoundingModeMask) {
1419 *rounded = floor(toRound + 0.5);
1420 *rounded_int =
static_cast<int64_t
>(*rounded);
1421 if ((*rounded_int & 1) != 0 && *rounded_int - toRound == 0.5) {
1429 *rounded = trunc(toRound);
1430 *rounded_int =
static_cast<int64_t
>(*rounded);
1433 *rounded = ceil(toRound);
1434 *rounded_int =
static_cast<int64_t
>(*rounded);
1437 *rounded = floor(toRound);
1438 *rounded_int =
static_cast<int64_t
>(*rounded);
1444void Simulator::set_pc(int64_t value) {
1445 pc_modified_ =
true;
1449bool Simulator::has_bad_pc()
const {
1454int64_t Simulator::get_pc()
const {
return registers_[
pc]; }
1457void Simulator::DieOrDebug() {
1459 Loong64Debugger dbg(
this);
1466void Simulator::TraceRegWr(int64_t value, TraceType t) {
1474 v.fmt_int64 =
value;
1478 base::SNPrintF(trace_buf_,
1479 "%016" PRIx64
" (%" PRId64
") int32:%" PRId32
1481 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0]);
1484 base::SNPrintF(trace_buf_,
1485 "%016" PRIx64
" (%" PRId64
") int64:%" PRId64
1487 value, icount_, value, value);
1490 base::SNPrintF(trace_buf_,
"%016" PRIx64
" (%" PRId64
") flt:%e",
1491 v.fmt_int64, icount_, v.fmt_float[0]);
1494 base::SNPrintF(trace_buf_,
"%016" PRIx64
" (%" PRId64
") dbl:%e",
1495 v.fmt_int64, icount_, v.fmt_double);
1498 base::SNPrintF(trace_buf_,
1499 "%016" PRIx64
" (%" PRId64
") flt:%e dbl:%e",
1500 v.fmt_int64, icount_, v.fmt_float[0], v.fmt_double);
1503 base::SNPrintF(trace_buf_,
1504 "%016" PRIx64
" (%" PRId64
") int32:%" PRId32
1505 " uint32:%" PRIu32
" int64:%" PRId64
" uint64:%" PRIu64,
1506 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0],
1507 v.fmt_int64, v.fmt_int64);
1516void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) {
1524 v.fmt_int64 =
value;
1528 base::SNPrintF(trace_buf_,
1529 "%016" PRIx64
" <-- [%016" PRIx64
"] (%" PRId64
1530 ") int32:%" PRId32
" uint32:%" PRIu32,
1531 v.fmt_int64, addr, icount_, v.fmt_int32[0],
1535 base::SNPrintF(trace_buf_,
1536 "%016" PRIx64
" <-- [%016" PRIx64
"] (%" PRId64
1537 ") int64:%" PRId64
" uint64:%" PRIu64,
1538 value, addr, icount_, value, value);
1541 base::SNPrintF(trace_buf_,
1542 "%016" PRIx64
" <-- [%016" PRIx64
"] (%" PRId64
1544 v.fmt_int64, addr, icount_, v.fmt_float[0]);
1547 base::SNPrintF(trace_buf_,
1548 "%016" PRIx64
" <-- [%016" PRIx64
"] (%" PRId64
1550 v.fmt_int64, addr, icount_, v.fmt_double);
1553 base::SNPrintF(trace_buf_,
1554 "%016" PRIx64
" <-- [%016" PRIx64
"] (%" PRId64
1556 v.fmt_int64, addr, icount_, v.fmt_float[0],
1565void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) {
1569 base::SNPrintF(trace_buf_,
1570 " %02" PRIx8
" --> [%016" PRIx64
1572 static_cast<uint8_t
>(value), addr, icount_);
1575 base::SNPrintF(trace_buf_,
1576 " %04" PRIx16
" --> [%016" PRIx64
1578 static_cast<uint16_t>(value), addr, icount_);
1581 base::SNPrintF(trace_buf_,
1582 " %08" PRIx32
" --> [%016" PRIx64
"] (%" PRId64
1584 static_cast<uint32_t
>(value), addr, icount_);
1587 base::SNPrintF(trace_buf_,
1588 "%016" PRIx64
" --> [%016" PRIx64
"] (%" PRId64
" )",
1589 value, addr, icount_);
1597template <
typename T>
1598void Simulator::TraceMemRd(int64_t addr, T value) {
1600 switch (
sizeof(T)) {
1602 base::SNPrintF(trace_buf_,
1603 "%08" PRIx8
" <-- [%08" PRIx64
"] (%" PRIu64
1604 ") int8:%" PRId8
" uint8:%" PRIu8,
1605 static_cast<uint8_t
>(value), addr, icount_,
1606 static_cast<int8_t
>(value),
static_cast<uint8_t
>(value));
1609 base::SNPrintF(trace_buf_,
1610 "%08" PRIx16
" <-- [%08" PRIx64
"] (%" PRIu64
1611 ") int16:%" PRId16
" uint16:%" PRIu16,
1612 static_cast<uint16_t>(value), addr, icount_,
1617 base::SNPrintF(trace_buf_,
1618 "%08" PRIx32
" <-- [%08" PRIx64
"] (%" PRIu64
1619 ") int32:%" PRId32
" uint32:%" PRIu32,
1620 static_cast<uint32_t
>(value), addr, icount_,
1622 static_cast<uint32_t
>(value));
1625 base::SNPrintF(trace_buf_,
1626 "%08" PRIx64
" <-- [%08" PRIx64
"] (%" PRIu64
1627 ") int64:%" PRId64
" uint64:%" PRIu64,
1628 static_cast<uint64_t
>(value), addr, icount_,
1629 static_cast<int64_t
>(value),
1630 static_cast<uint64_t
>(value));
1638template <
typename T>
1639void Simulator::TraceMemWr(int64_t addr, T value) {
1641 switch (
sizeof(T)) {
1643 base::SNPrintF(trace_buf_,
1644 " %02" PRIx8
" --> [%08" PRIx64
"] (%" PRIu64
1646 static_cast<uint8_t
>(value), addr, icount_);
1649 base::SNPrintF(trace_buf_,
1650 " %04" PRIx16
" --> [%08" PRIx64
"] (%" PRIu64
")",
1651 static_cast<uint16_t>(value), addr, icount_);
1654 base::SNPrintF(trace_buf_,
1655 "%08" PRIx32
" --> [%08" PRIx64
"] (%" PRIu64
")",
1656 static_cast<uint32_t
>(value), addr, icount_);
1659 base::SNPrintF(trace_buf_,
1660 "%16" PRIx64
" --> [%08" PRIx64
"] (%" PRIu64
")",
1661 static_cast<uint64_t
>(value), addr, icount_);
1669bool Simulator::ProbeMemory(uintptr_t address, uintptr_t access_size) {
1670#if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
1671 uintptr_t last_accessed_byte = address + access_size - 1;
1673 uintptr_t landing_pad =
1674 trap_handler::ProbeMemory(last_accessed_byte, current_pc);
1675 if (!landing_pad)
return true;
1676 set_pc(landing_pad);
1684int32_t Simulator::ReadW(int64_t addr, Instruction*
instr, TraceType t) {
1685 if (addr >= 0 && addr < 0x400) {
1687 PrintF(
"Memory read from bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1689 addr,
reinterpret_cast<intptr_t
>(
instr));
1694 local_monitor_.NotifyLoad();
1696 TraceMemRd(addr,
static_cast<int64_t
>(*ptr), t);
1701uint32_t Simulator::ReadWU(int64_t addr, Instruction*
instr) {
1702 if (addr >= 0 && addr < 0x400) {
1704 PrintF(
"Memory read from bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1706 addr,
reinterpret_cast<intptr_t
>(
instr));
1711 local_monitor_.NotifyLoad();
1712 uint32_t* ptr =
reinterpret_cast<uint32_t*
>(addr);
1713 TraceMemRd(addr,
static_cast<int64_t
>(*ptr), WORD);
1718void Simulator::WriteW(int64_t addr, int32_t value, Instruction*
instr) {
1719 if (addr >= 0 && addr < 0x400) {
1721 PrintF(
"Memory write to bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1723 addr,
reinterpret_cast<intptr_t
>(
instr));
1728 local_monitor_.NotifyStore();
1729 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1730 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1731 TraceMemWr(addr, value, WORD);
1732 int* ptr =
reinterpret_cast<int*
>(addr);
1738void Simulator::WriteConditionalW(int64_t addr, int32_t value,
1739 Instruction*
instr, int32_t* done) {
1740 if (addr >= 0 && addr < 0x400) {
1742 PrintF(
"Memory write to bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1744 addr,
reinterpret_cast<intptr_t
>(
instr));
1748 if ((addr & 0x3) == 0) {
1749 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1750 if (local_monitor_.NotifyStoreConditional(addr, TransactionSize::Word) &&
1751 GlobalMonitor::Get()->NotifyStoreConditional_Locked(
1752 addr, &global_monitor_thread_)) {
1753 local_monitor_.NotifyStore();
1754 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1755 TraceMemWr(addr, value, WORD);
1756 int* ptr =
reinterpret_cast<int*
>(addr);
1764 PrintF(
"Unaligned write at 0x%08" PRIx64
" , pc=0x%08" V8PRIxPTR "\n", addr,
1765 reinterpret_cast<intptr_t
>(
instr));
1769int64_t Simulator::Read2W(int64_t addr, Instruction*
instr) {
1770 if (addr >= 0 && addr < 0x400) {
1772 PrintF(
"Memory read from bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1774 addr,
reinterpret_cast<intptr_t
>(
instr));
1779 local_monitor_.NotifyLoad();
1780 int64_t* ptr =
reinterpret_cast<int64_t*
>(addr);
1781 TraceMemRd(addr, *ptr);
1786void Simulator::Write2W(int64_t addr, int64_t value, Instruction*
instr) {
1787 if (addr >= 0 && addr < 0x400) {
1789 PrintF(
"Memory write to bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1791 addr,
reinterpret_cast<intptr_t
>(
instr));
1796 local_monitor_.NotifyStore();
1797 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1798 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1799 TraceMemWr(addr, value,
DWORD);
1800 int64_t* ptr =
reinterpret_cast<int64_t*
>(addr);
1806void Simulator::WriteConditional2W(int64_t addr, int64_t value,
1807 Instruction*
instr, int32_t* done) {
1808 if (addr >= 0 && addr < 0x400) {
1810 PrintF(
"Memory write to bad address: 0x%08" PRIx64
" , pc=0x%08" PRIxPTR
1812 addr,
reinterpret_cast<intptr_t
>(
instr));
1816 if ((addr & kPointerAlignmentMask) == 0) {
1817 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1818 if (local_monitor_.NotifyStoreConditional(addr,
1819 TransactionSize::DoubleWord) &&
1820 GlobalMonitor::Get()->NotifyStoreConditional_Locked(
1821 addr, &global_monitor_thread_)) {
1822 local_monitor_.NotifyStore();
1823 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1824 TraceMemWr(addr, value,
DWORD);
1825 int64_t* ptr =
reinterpret_cast<int64_t*
>(addr);
1833 PrintF(
"Unaligned write at 0x%08" PRIx64
" , pc=0x%08" V8PRIxPTR "\n", addr,
1834 reinterpret_cast<intptr_t
>(
instr));
1838double Simulator::ReadD(int64_t addr, Instruction*
instr) {
1839 local_monitor_.NotifyLoad();
1840 double* ptr =
reinterpret_cast<double*
>(addr);
1844void Simulator::WriteD(int64_t addr,
double value, Instruction*
instr) {
1845 local_monitor_.NotifyStore();
1846 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1847 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1848 double* ptr =
reinterpret_cast<double*
>(addr);
1853uint16_t Simulator::ReadHU(int64_t addr, Instruction*
instr) {
1854 local_monitor_.NotifyLoad();
1856 TraceMemRd(addr,
static_cast<int64_t
>(*ptr));
1860int16_t Simulator::ReadH(int64_t addr, Instruction*
instr) {
1861 local_monitor_.NotifyLoad();
1863 TraceMemRd(addr,
static_cast<int64_t
>(*ptr));
1867void Simulator::WriteH(int64_t addr, uint16_t value, Instruction*
instr) {
1868 local_monitor_.NotifyStore();
1869 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1870 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1871 TraceMemWr(addr, value, HALF);
1877void Simulator::WriteH(int64_t addr, int16_t value, Instruction*
instr) {
1878 local_monitor_.NotifyStore();
1879 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1880 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1881 TraceMemWr(addr, value, HALF);
1887uint32_t Simulator::ReadBU(int64_t addr) {
1888 local_monitor_.NotifyLoad();
1889 uint8_t* ptr =
reinterpret_cast<uint8_t*
>(addr);
1890 TraceMemRd(addr,
static_cast<int64_t
>(*ptr));
1894int32_t Simulator::ReadB(int64_t addr) {
1895 local_monitor_.NotifyLoad();
1896 int8_t* ptr =
reinterpret_cast<int8_t*
>(addr);
1897 TraceMemRd(addr,
static_cast<int64_t
>(*ptr));
1901void Simulator::WriteB(int64_t addr, uint8_t value) {
1902 local_monitor_.NotifyStore();
1903 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1904 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1905 TraceMemWr(addr, value, BYTE);
1906 uint8_t* ptr =
reinterpret_cast<uint8_t*
>(addr);
1910void Simulator::WriteB(int64_t addr, int8_t value) {
1911 local_monitor_.NotifyStore();
1912 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1913 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1914 TraceMemWr(addr, value, BYTE);
1915 int8_t* ptr =
reinterpret_cast<int8_t*
>(addr);
1919template <
typename T>
1920T Simulator::ReadMem(int64_t addr, Instruction*
instr) {
1921 int alignment_mask = (1 <<
sizeof(
T)) - 1;
1922 if ((addr & alignment_mask) == 0) {
1923 local_monitor_.NotifyLoad();
1924 T* ptr =
reinterpret_cast<T*
>(addr);
1925 TraceMemRd(addr, *ptr);
1928 PrintF(
"Unaligned read of type sizeof(%ld) at 0x%08lx, pc=0x%08" V8PRIxPTR
1930 sizeof(T), addr,
reinterpret_cast<intptr_t
>(
instr));
1935template <
typename T>
1936void Simulator::WriteMem(int64_t addr, T value, Instruction*
instr) {
1937 int alignment_mask = (1 <<
sizeof(
T)) - 1;
1938 if ((addr & alignment_mask) == 0) {
1939 local_monitor_.NotifyStore();
1940 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
1941 GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_thread_);
1942 T* ptr =
reinterpret_cast<T*
>(addr);
1944 TraceMemWr(addr, value);
1947 PrintF(
"Unaligned write of type sizeof(%ld) at 0x%08lx, pc=0x%08" V8PRIxPTR
1949 sizeof(T), addr,
reinterpret_cast<intptr_t
>(
instr));
1954uintptr_t Simulator::StackLimit(uintptr_t c_limit)
const {
1957 if (base::Stack::GetCurrentStackPosition() < c_limit) {
1966uintptr_t Simulator::StackBase()
const {
1967 return reinterpret_cast<uintptr_t
>(stack_) + UsableStackSize();
1970base::Vector<uint8_t> Simulator::GetCentralStackView()
const {
1974 return base::VectorOf(
1975 reinterpret_cast<uint8_t*
>(stack_) + kStackProtectionSize,
1984 visitor->
VisitPointer(
reinterpret_cast<const void*
>(get_register(
i)));
1986 for (
const void*
const* current =
1987 reinterpret_cast<const void* const*
>(get_sp());
1989 const void* address = *
current;
1990 if (address ==
nullptr) {
1998void Simulator::Format(Instruction*
instr,
const char* format) {
1999 PrintF(
"Simulator found unsupported instruction:\n 0x%08" PRIxPTR
" : %s\n",
2000 reinterpret_cast<intptr_t
>(
instr), format);
2012 int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4,
2013 int64_t arg5, int64_t arg6, int64_t arg7, int64_t arg8, int64_t arg9,
2014 int64_t arg10, int64_t arg11, int64_t arg12, int64_t arg13, int64_t arg14,
2015 int64_t arg15, int64_t arg16, int64_t arg17, int64_t arg18, int64_t arg19);
2018using SimulatorRuntimeCompareCall = int64_t (*)(
double darg0,
double darg1);
2019using SimulatorRuntimeFPFPCall = double (*)(
double darg0,
double darg1);
2020using SimulatorRuntimeFPCall = double (*)(
double darg0);
2021using SimulatorRuntimeFPIntCall = double (*)(
double darg0,
int32_t arg0);
2022using SimulatorRuntimeIntFPCall =
int32_t (*)(
double darg0);
2025using SimulatorRuntimeFPTaggedCall = double (*)(int64_t arg0, int64_t arg1,
2026 int64_t arg2, int64_t arg3);
2030using SimulatorRuntimeDirectApiCall = void (*)(int64_t arg0);
2033using SimulatorRuntimeDirectGetterCall = void (*)(int64_t arg0, int64_t arg1);
2035using MixedRuntimeCall_0 = AnyCType (*)();
2037#define BRACKETS(ident, N) ident[N]
2039#define REP_0(expr, FMT)
2040#define REP_1(expr, FMT) FMT(expr, 0)
2041#define REP_2(expr, FMT) REP_1(expr, FMT), FMT(expr, 1)
2042#define REP_3(expr, FMT) REP_2(expr, FMT), FMT(expr, 2)
2043#define REP_4(expr, FMT) REP_3(expr, FMT), FMT(expr, 3)
2044#define REP_5(expr, FMT) REP_4(expr, FMT), FMT(expr, 4)
2045#define REP_6(expr, FMT) REP_5(expr, FMT), FMT(expr, 5)
2046#define REP_7(expr, FMT) REP_6(expr, FMT), FMT(expr, 6)
2047#define REP_8(expr, FMT) REP_7(expr, FMT), FMT(expr, 7)
2048#define REP_9(expr, FMT) REP_8(expr, FMT), FMT(expr, 8)
2049#define REP_10(expr, FMT) REP_9(expr, FMT), FMT(expr, 9)
2050#define REP_11(expr, FMT) REP_10(expr, FMT), FMT(expr, 10)
2051#define REP_12(expr, FMT) REP_11(expr, FMT), FMT(expr, 11)
2052#define REP_13(expr, FMT) REP_12(expr, FMT), FMT(expr, 12)
2053#define REP_14(expr, FMT) REP_13(expr, FMT), FMT(expr, 13)
2054#define REP_15(expr, FMT) REP_14(expr, FMT), FMT(expr, 14)
2055#define REP_16(expr, FMT) REP_15(expr, FMT), FMT(expr, 15)
2056#define REP_17(expr, FMT) REP_16(expr, FMT), FMT(expr, 16)
2057#define REP_18(expr, FMT) REP_17(expr, FMT), FMT(expr, 17)
2058#define REP_19(expr, FMT) REP_18(expr, FMT), FMT(expr, 18)
2059#define REP_20(expr, FMT) REP_19(expr, FMT), FMT(expr, 19)
2061#define GEN_MAX_PARAM_COUNT(V) \
2084#define MIXED_RUNTIME_CALL(N) \
2085 using MixedRuntimeCall_##N = AnyCType (*)(REP_##N(AnyCType arg, CONCAT));
2087GEN_MAX_PARAM_COUNT(MIXED_RUNTIME_CALL)
2088#undef MIXED_RUNTIME_CALL
2090#define CALL_ARGS(N) REP_##N(args, BRACKETS)
2091#define CALL_TARGET_VARARG(N) \
2092 if (signature.ParameterCount() == N) { \
2093 MixedRuntimeCall_##N target = \
2094 reinterpret_cast<MixedRuntimeCall_##N>(target_address); \
2095 result = target(CALL_ARGS(N)); \
2099#define PARAM_REGISTERS a0, a1, a2, a3, a4, a5, a6, a7
2100#define RETURN_REGISTER a0
2101#define FP_PARAM_REGISTERS f0, f1, f2, f3, f4, f5, f6, f7
2102#define FP_RETURN_REGISTER f0
2104void Simulator::CallAnyCTypeFunction(Address target_address,
2105 const EncodedCSignature& signature) {
2106 const int64_t* stack_pointer =
reinterpret_cast<int64_t*
>(get_register(sp));
2107 const double* double_stack_pointer =
2108 reinterpret_cast<double*
>(get_register(sp));
2110 const Register kParamRegisters[] = {PARAM_REGISTERS};
2111 const FPURegister kFPParamRegisters[] = {FP_PARAM_REGISTERS};
2113 int num_gp_params = 0, num_fp_params = 0, num_stack_params = 0;
2115 CHECK_LE(signature.ParameterCount(), kMaxCParameters);
2116 static_assert(
sizeof(AnyCType) == 8,
"AnyCType is assumed to be 64-bit.");
2117 AnyCType
args[kMaxCParameters];
2118 for (
int i = 0;
i < signature.ParameterCount(); ++
i) {
2119 if (signature.IsFloat(
i)) {
2120 if (num_fp_params < 8) {
2121 args[
i].double_value =
2122 get_fpu_register_double(kFPParamRegisters[num_fp_params++]);
2123 }
else if (num_gp_params < 8) {
2124 args[
i].int64_value = get_register(kParamRegisters[num_gp_params++]);
2126 args[
i].double_value = double_stack_pointer[num_stack_params++];
2129 if (num_gp_params < 8) {
2130 args[
i].int64_value = get_register(kParamRegisters[num_gp_params++]);
2132 args[
i].int64_value = stack_pointer[num_stack_params++];
2137 GEN_MAX_PARAM_COUNT(CALL_TARGET_VARARG)
2141 static_assert(20 == kMaxCParameters,
2142 "If you've changed kMaxCParameters, please change the "
2143 "GEN_MAX_PARAM_COUNT macro.");
2145#undef CALL_TARGET_VARARG
2147#undef GEN_MAX_PARAM_COUNT
2149 if (signature.IsReturnFloat()) {
2150 set_fpu_register_double(FP_RETURN_REGISTER,
result.double_value);
2152 set_register(RETURN_REGISTER,
result.int64_value);
2156#undef PARAM_REGISTERS
2157#undef RETURN_REGISTER
2158#undef FP_PARAM_REGISTERS
2159#undef FP_RETURN_REGISTER
2163void Simulator::SoftwareInterrupt() {
2164 int32_t opcode_hi15 = instr_.Bits(31, 17);
2166 uint32_t code = instr_.Bits(14, 0);
2168 if (instr_.InstructionBits() == rtCallRedirInstr) {
2169 Redirection* redirection = Redirection::FromInstruction(instr_.instr());
2172 int64_t saved_ra = get_register(ra);
2174 reinterpret_cast<intptr_t
>(redirection->external_function());
2177 reinterpret_cast<Address>(redirection->external_function());
2178 SimulatorData* simulator_data =
isolate_->simulator_data();
2180 const EncodedCSignature& signature =
2181 simulator_data->GetSignatureForTarget(func_addr);
2182 if (signature.IsValid()) {
2183 CHECK_EQ(redirection->type(), ExternalReference::FAST_C_CALL);
2184 CallAnyCTypeFunction(external, signature);
2185 set_register(ra, saved_ra);
2186 set_pc(get_register(ra));
2190 int64_t* stack_pointer =
reinterpret_cast<int64_t*
>(get_register(sp));
2192 int64_t arg0 = get_register(a0);
2193 int64_t arg1 = get_register(a1);
2194 int64_t arg2 = get_register(a2);
2195 int64_t arg3 = get_register(a3);
2196 int64_t arg4 = get_register(a4);
2197 int64_t arg5 = get_register(a5);
2198 int64_t arg6 = get_register(a6);
2199 int64_t arg7 = get_register(a7);
2200 int64_t arg8 = stack_pointer[0];
2201 int64_t arg9 = stack_pointer[1];
2202 int64_t arg10 = stack_pointer[2];
2203 int64_t arg11 = stack_pointer[3];
2204 int64_t arg12 = stack_pointer[4];
2205 int64_t arg13 = stack_pointer[5];
2206 int64_t arg14 = stack_pointer[6];
2207 int64_t arg15 = stack_pointer[7];
2208 int64_t arg16 = stack_pointer[8];
2209 int64_t arg17 = stack_pointer[9];
2210 int64_t arg18 = stack_pointer[10];
2211 int64_t arg19 = stack_pointer[11];
2212 static_assert(kMaxCParameters == 20);
2215 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
2216 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
2217 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
2218 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL) ||
2219 (redirection->type() == ExternalReference::BUILTIN_INT_FP_CALL);
2226 double dval0, dval1;
2228 int64_t iresult = 0;
2230 GetFpArgs(&dval0, &dval1, &ival);
2231 SimulatorRuntimeCall generic_target =
2232 reinterpret_cast<SimulatorRuntimeCall
>(external);
2234 switch (redirection->type()) {
2235 case ExternalReference::BUILTIN_FP_FP_CALL:
2236 case ExternalReference::BUILTIN_COMPARE_CALL:
2237 PrintF(
"Call to host function at %p with args %f, %f",
2241 case ExternalReference::BUILTIN_FP_CALL:
2242 PrintF(
"Call to host function at %p with arg %f",
2246 case ExternalReference::BUILTIN_FP_INT_CALL:
2247 PrintF(
"Call to host function at %p with args %f, %d",
2251 case ExternalReference::BUILTIN_INT_FP_CALL:
2252 PrintF(
"Call to host function at %p with args %f",
2260 switch (redirection->type()) {
2261 case ExternalReference::BUILTIN_COMPARE_CALL: {
2262 SimulatorRuntimeCompareCall target =
2263 reinterpret_cast<SimulatorRuntimeCompareCall
>(external);
2264 iresult =
target(dval0, dval1);
2265 set_register(v0,
static_cast<int64_t
>(iresult));
2269 case ExternalReference::BUILTIN_FP_FP_CALL: {
2270 SimulatorRuntimeFPFPCall target =
2271 reinterpret_cast<SimulatorRuntimeFPFPCall
>(external);
2272 dresult =
target(dval0, dval1);
2273 SetFpResult(dresult);
2276 case ExternalReference::BUILTIN_FP_CALL: {
2277 SimulatorRuntimeFPCall target =
2278 reinterpret_cast<SimulatorRuntimeFPCall
>(external);
2280 SetFpResult(dresult);
2283 case ExternalReference::BUILTIN_FP_INT_CALL: {
2284 SimulatorRuntimeFPIntCall target =
2285 reinterpret_cast<SimulatorRuntimeFPIntCall
>(external);
2286 dresult =
target(dval0, ival);
2287 SetFpResult(dresult);
2290 case ExternalReference::BUILTIN_INT_FP_CALL: {
2291 SimulatorRuntimeIntFPCall target =
2292 reinterpret_cast<SimulatorRuntimeIntFPCall
>(external);
2294 set_register(a0,
static_cast<int64_t
>(iresult));
2301 switch (redirection->type()) {
2302 case ExternalReference::BUILTIN_COMPARE_CALL:
2303 case ExternalReference::BUILTIN_INT_FP_CALL:
2306 case ExternalReference::BUILTIN_FP_FP_CALL:
2307 case ExternalReference::BUILTIN_FP_CALL:
2308 case ExternalReference::BUILTIN_FP_INT_CALL:
2309 PrintF(
"Returned %f\n", dresult);
2315 }
else if (redirection->type() ==
2316 ExternalReference::BUILTIN_FP_POINTER_CALL) {
2318 PrintF(
"Call to host function at %p args %08" PRIx64
" \n",
2319 reinterpret_cast<void*
>(external), arg0);
2321 SimulatorRuntimeFPTaggedCall target =
2322 reinterpret_cast<SimulatorRuntimeFPTaggedCall
>(external);
2323 double dresult =
target(arg0, arg1, arg2, arg3);
2324 SetFpResult(dresult);
2326 PrintF(
"Returned %f\n", dresult);
2328 }
else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
2330 PrintF(
"Call to host function at %p args %08" PRIx64
" \n",
2331 reinterpret_cast<void*
>(external), arg0);
2333 SimulatorRuntimeDirectApiCall target =
2334 reinterpret_cast<SimulatorRuntimeDirectApiCall
>(external);
2336 }
else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
2338 PrintF(
"Call to host function at %p args %08" PRIx64
" %08" PRIx64
2340 reinterpret_cast<void*
>(external), arg0, arg1);
2342 SimulatorRuntimeDirectGetterCall target =
2343 reinterpret_cast<SimulatorRuntimeDirectGetterCall
>(external);
2346 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
2347 redirection->type() == ExternalReference::BUILTIN_CALL_PAIR);
2348 SimulatorRuntimeCall target =
2349 reinterpret_cast<SimulatorRuntimeCall
>(external);
2352 "Call to host function at %p "
2353 "args %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
2354 " , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
2355 " , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
2356 " , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
2357 " , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
" , %08" PRIx64
2359 reinterpret_cast<void*
>(
FUNCTION_ADDR(target)), arg0, arg1, arg2,
2360 arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12,
2361 arg13, arg14, arg15, arg16, arg17, arg18, arg19);
2364 arg8, arg9, arg10, arg11, arg12, arg13, arg14,
2365 arg15, arg16, arg17, arg18, arg19);
2366 set_register(v0, (int64_t)(
result.x));
2367 set_register(v1, (int64_t)(
result.y));
2370 PrintF(
"Returned %08" PRIx64
" : %08" PRIx64
" \n", get_register(v1),
2373 set_register(ra, saved_ra);
2374 set_pc(get_register(ra));
2376 }
else if (code <= kMaxStopCode) {
2377 if (IsWatchpoint(code)) {
2378 PrintWatchpoint(code);
2380 IncreaseStopCounter(code);
2381 HandleStop(code, instr_.instr());
2385 Loong64Debugger dbg(
this);
2391bool Simulator::IsWatchpoint(uint64_t code) {
2392 return (code <= kMaxWatchpointCode);
2395void Simulator::PrintWatchpoint(uint64_t code) {
2396 Loong64Debugger dbg(
this);
2398 PrintF(
"\n---- break %" PRId64
" marker: %3d (instr count: %8" PRId64
2400 "----------------------------------",
2401 code, break_count_, icount_);
2405void Simulator::HandleStop(uint64_t code, Instruction*
instr) {
2408 if (IsEnabledStop(code)) {
2409 Loong64Debugger dbg(
this);
2414bool Simulator::IsStopInstruction(Instruction*
instr) {
2416 uint32_t code =
static_cast<uint32_t
>(
instr->Bits(14, 0));
2421bool Simulator::IsEnabledStop(uint64_t code) {
2424 return !(watched_stops_[
code].count & kStopDisabledBit);
2427void Simulator::EnableStop(uint64_t code) {
2428 if (!IsEnabledStop(code)) {
2429 watched_stops_[
code].count &= ~kStopDisabledBit;
2433void Simulator::DisableStop(uint64_t code) {
2434 if (IsEnabledStop(code)) {
2435 watched_stops_[
code].count |= kStopDisabledBit;
2439void Simulator::IncreaseStopCounter(uint64_t code) {
2441 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7FFFFFFF) {
2442 PrintF(
"Stop counter for code %" PRId64
2443 " has overflowed.\n"
2444 "Enabling this code and reseting the counter to 0.\n",
2446 watched_stops_[
code].count = 0;
2449 watched_stops_[
code].count++;
2454void Simulator::PrintStopInfo(uint64_t code) {
2455 if (code <= kMaxWatchpointCode) {
2456 PrintF(
"That is a watchpoint, not a stop.\n");
2458 }
else if (code > kMaxStopCode) {
2459 PrintF(
"Code too large, only %u stops can be used\n", kMaxStopCode + 1);
2462 const char* state = IsEnabledStop(code) ?
"Enabled" :
"Disabled";
2463 int32_t count = watched_stops_[
code].count & ~kStopDisabledBit;
2466 if (watched_stops_[code].desc) {
2467 PrintF(
"stop %" PRId64
" - 0x%" PRIx64
" : \t%s, \tcounter = %i, \t%s\n",
2468 code, code, state, count, watched_stops_[code].desc);
2470 PrintF(
"stop %" PRId64
" - 0x%" PRIx64
" : \t%s, \tcounter = %i\n", code,
2471 code, state, count);
2476void Simulator::SignalException(Exception e) {
2477 FATAL(
"Error: Exception %i raised.",
static_cast<int>(e));
2480template <
typename T>
2484double FPAbs<double>(
double a) {
2489float FPAbs<float>(
float a) {
2493template <
typename T>
2494static bool FPUProcessNaNsAndZeros(T a, T b, MaxMinKind
kind, T*
result) {
2495 if (std::isnan(a) && std::isnan(b)) {
2497 }
else if (std::isnan(a)) {
2499 }
else if (std::isnan(b)) {
2501 }
else if (b == a) {
2505 *
result = std::signbit(b) -
static_cast<int>(
kind) ? b : a;
2512template <
typename T>
2513static T FPUMin(T a, T b) {
2515 if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, &
result)) {
2518 return b < a ? b :
a;
2522template <
typename T>
2523static T FPUMax(T a, T b) {
2525 if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMax, &
result)) {
2528 return b > a ? b :
a;
2532template <
typename T>
2533static T FPUMinA(T a, T b) {
2535 if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, &
result)) {
2536 if (FPAbs(a) < FPAbs(b)) {
2538 }
else if (FPAbs(b) < FPAbs(a)) {
2547template <
typename T>
2548static T FPUMaxA(T a, T b) {
2550 if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, &
result)) {
2551 if (FPAbs(a) > FPAbs(b)) {
2553 }
else if (FPAbs(b) > FPAbs(a)) {
2562enum class KeepSign :
bool { no =
false, yes };
2564template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
2566T FPUCanonalizeNaNArg(T
result, T arg, KeepSign keepSign = KeepSign::no) {
2568 T qNaN = std::numeric_limits<T>::quiet_NaN();
2569 if (keepSign == KeepSign::yes) {
2570 return std::copysign(qNaN,
result);
2575template <
typename T>
2576T FPUCanonalizeNaNArgs(T
result, KeepSign keepSign, T first) {
2577 if (std::isnan(first)) {
2578 return FPUCanonalizeNaNArg(
result, first, keepSign);
2583template <
typename T,
typename... Args>
2584T FPUCanonalizeNaNArgs(T
result, KeepSign keepSign, T first, Args...
args) {
2585 if (std::isnan(first)) {
2586 return FPUCanonalizeNaNArg(
result, first, keepSign);
2588 return FPUCanonalizeNaNArgs(
result, keepSign,
args...);
2591template <
typename Func,
typename T,
typename... Args>
2592T FPUCanonalizeOperation(Func f, T first, Args...
args) {
2593 return FPUCanonalizeOperation(f, KeepSign::no, first,
args...);
2596template <
typename Func,
typename T,
typename... Args>
2597T FPUCanonalizeOperation(Func f, KeepSign keepSign, T first, Args...
args) {
2599 if (std::isnan(
result)) {
2606void Simulator::DecodeTypeOp6() {
2609 int64_t next_pc = bad_ra;
2612 auto BranchAndLinkHelper = [
this, &next_pc]() {
2613 int64_t current_pc = get_pc();
2614 set_register(ra, current_pc + kInstrSize);
2616 static_cast<uint32_t
>(instr_.Bits(25, 10) << 16) >> 16;
2617 int32_t offs26_high10 =
static_cast<int32_t>(instr_.Bits(9, 0) << 22) >> 6;
2618 int32_t offs26 = offs26_low16 | offs26_high10;
2619 next_pc = current_pc + (offs26 << 2);
2620 printf_instr(
"Offs26: %08x\n", offs26);
2624 auto BranchOff16Helper = [
this, &next_pc](
bool do_branch) {
2625 int64_t current_pc = get_pc();
2626 int32_t offs16 =
static_cast<int32_t>(instr_.Bits(25, 10) << 16) >> 16;
2627 printf_instr(
"Offs16: %08x\n", offs16);
2629 next_pc = current_pc + offs;
2633 auto BranchOff21Helper = [
this, &next_pc](
bool do_branch) {
2634 int64_t current_pc = get_pc();
2636 static_cast<uint32_t
>(instr_.Bits(25, 10) << 16) >> 16;
2637 int32_t offs21_high5 =
static_cast<int32_t>(instr_.Bits(4, 0) << 27) >> 11;
2638 int32_t offs = offs21_low16 | offs21_high5;
2639 printf_instr(
"Offs21: %08x\n", offs);
2641 next_pc = current_pc + offs;
2645 auto BranchOff26Helper = [
this, &next_pc]() {
2646 int64_t current_pc = get_pc();
2648 static_cast<uint32_t
>(instr_.Bits(25, 10) << 16) >> 16;
2649 int32_t offs26_high10 =
static_cast<int32_t>(instr_.Bits(9, 0) << 22) >> 6;
2650 int32_t offs26 = offs26_low16 | offs26_high10;
2651 next_pc = current_pc + (offs26 << 2);
2652 printf_instr(
"Offs26: %08x\n", offs26);
2656 auto JumpOff16Helper = [
this, &next_pc]() {
2657 int32_t offs16 =
static_cast<int32_t>(instr_.Bits(25, 10) << 16) >> 16;
2658 printf_instr(
"JIRL\t %s: %016lx, %s: %016lx, offs16: %x\n",
2659 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2661 set_register(rd_reg(), get_pc() + kInstrSize);
2662 next_pc = rj() + (offs16 << 2);
2666 switch (instr_.Bits(31, 26) << 26) {
2668 printf_instr(
"ADDU16I_D\t %s: %016lx, %s: %016lx, si16: %d\n",
2669 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2672 alu_out =
static_cast<int64_t
>(si16_upper) + rj();
2673 SetResult(rd_reg(), alu_out);
2677 printf_instr(
"BEQZ\t %s: %016lx, ", Registers::Name(rj_reg()), rj());
2678 BranchOff21Helper(rj() == 0);
2681 printf_instr(
"BNEZ\t %s: %016lx, ", Registers::Name(rj_reg()), rj());
2682 BranchOff21Helper(rj() != 0);
2685 if (instr_.Bits(9, 8) == 0b00) {
2687 printf_instr(
"BCEQZ\t fcc%d: %s, ", cj_reg(), cj() ?
"True" :
"False");
2688 BranchOff21Helper(cj() ==
false);
2689 }
else if (instr_.Bits(9, 8) == 0b01) {
2691 printf_instr(
"BCNEZ\t fcc%d: %s, ", cj_reg(), cj() ?
"True" :
"False");
2692 BranchOff21Helper(cj() ==
true);
2702 printf_instr(
"B\t ");
2703 BranchOff26Helper();
2706 printf_instr(
"BL\t ");
2707 BranchAndLinkHelper();
2710 printf_instr(
"BEQ\t %s: %016lx, %s, %016lx, ", Registers::Name(rj_reg()),
2711 rj(), Registers::Name(rd_reg()), rd());
2712 BranchOff16Helper(rj() == rd());
2715 printf_instr(
"BNE\t %s: %016lx, %s, %016lx, ", Registers::Name(rj_reg()),
2716 rj(), Registers::Name(rd_reg()), rd());
2717 BranchOff16Helper(rj() != rd());
2720 printf_instr(
"BLT\t %s: %016lx, %s, %016lx, ", Registers::Name(rj_reg()),
2721 rj(), Registers::Name(rd_reg()), rd());
2722 BranchOff16Helper(rj() < rd());
2725 printf_instr(
"BGE\t %s: %016lx, %s, %016lx, ", Registers::Name(rj_reg()),
2726 rj(), Registers::Name(rd_reg()), rd());
2727 BranchOff16Helper(rj() >= rd());
2730 printf_instr(
"BLTU\t %s: %016lx, %s, %016lx, ", Registers::Name(rj_reg()),
2731 rj(), Registers::Name(rd_reg()), rd());
2732 BranchOff16Helper(rj_u() < rd_u());
2735 printf_instr(
"BGEU\t %s: %016lx, %s, %016lx, ", Registers::Name(rj_reg()),
2736 rj(), Registers::Name(rd_reg()), rd());
2737 BranchOff16Helper(rj_u() >= rd_u());
2744void Simulator::DecodeTypeOp7() {
2747 switch (instr_.Bits(31, 25) << 25) {
2749 printf_instr(
"LU12I_W\t %s: %016lx, si20: %d\n",
2750 Registers::Name(rd_reg()), rd(), si20());
2752 SetResult(rd_reg(),
static_cast<int64_t
>(si20_upper));
2756 printf_instr(
"LU32I_D\t %s: %016lx, si20: %d\n",
2757 Registers::Name(rd_reg()), rd(), si20());
2758 int32_t si20_signExtend =
static_cast<int32_t>(si20() << 12) >> 12;
2759 int64_t lower_32bit_mask = 0xFFFFFFFF;
2760 alu_out = (
static_cast<int64_t
>(si20_signExtend) << 32) |
2761 (rd() & lower_32bit_mask);
2762 SetResult(rd_reg(), alu_out);
2766 printf_instr(
"PCADDI\t %s: %016lx, si20: %d\n", Registers::Name(rd_reg()),
2768 int32_t si20_signExtend =
static_cast<int32_t>(si20() << 12) >> 10;
2769 int64_t current_pc = get_pc();
2770 alu_out =
static_cast<int64_t
>(si20_signExtend) + current_pc;
2771 SetResult(rd_reg(), alu_out);
2775 printf_instr(
"PCALAU12I\t %s: %016lx, si20: %d\n",
2776 Registers::Name(rd_reg()), rd(), si20());
2778 int64_t current_pc = get_pc();
2779 int64_t clear_lower12bit_mask = 0xFFFFFFFFFFFFF000;
2780 alu_out =
static_cast<int64_t
>(si20_signExtend) + current_pc;
2781 SetResult(rd_reg(), alu_out & clear_lower12bit_mask);
2785 printf_instr(
"PCADDU12I\t %s: %016lx, si20: %d\n",
2786 Registers::Name(rd_reg()), rd(), si20());
2788 int64_t current_pc = get_pc();
2789 alu_out =
static_cast<int64_t
>(si20_signExtend) + current_pc;
2790 SetResult(rd_reg(), alu_out);
2794 printf_instr(
"PCADDU18I\t %s: %016lx, si20: %d\n",
2795 Registers::Name(rd_reg()), rd(), si20());
2796 int64_t si20_signExtend = (
static_cast<int64_t
>(si20()) << 44) >> 26;
2797 int64_t current_pc = get_pc();
2798 alu_out = si20_signExtend + current_pc;
2799 SetResult(rd_reg(), alu_out);
2807void Simulator::DecodeTypeOp8() {
2809 int64_t si14_se = (
static_cast<int64_t
>(si14()) << 50) >> 48;
2811 switch (instr_.Bits(31, 24) << 24) {
2813 printf_instr(
"LDPTR_W\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2814 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2816 if (!ProbeMemory(rj() + si14_se,
sizeof(int32_t)))
return;
2817 set_register(rd_reg(), ReadW(rj() + si14_se, instr_.instr()));
2820 printf_instr(
"STPTR_W\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2821 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2823 if (!ProbeMemory(rj() + si14_se,
sizeof(int32_t)))
return;
2824 WriteW(rj() + si14_se,
static_cast<int32_t>(rd()), instr_.instr());
2827 printf_instr(
"LDPTR_D\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2828 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2830 if (!ProbeMemory(rj() + si14_se,
sizeof(int64_t)))
return;
2831 set_register(rd_reg(), Read2W(rj() + si14_se, instr_.instr()));
2834 printf_instr(
"STPTR_D\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2835 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2837 if (!ProbeMemory(rj() + si14_se,
sizeof(int64_t)))
return;
2838 Write2W(rj() + si14_se, rd(), instr_.instr());
2841 printf_instr(
"LL_W\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2842 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2844 addr = si14_se + rj();
2845 if (!ProbeMemory(addr,
sizeof(int32_t)))
return;
2847 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
2848 set_register(rd_reg(), ReadW(addr, instr_.instr()));
2849 local_monitor_.NotifyLoadLinked(addr, TransactionSize::Word);
2850 GlobalMonitor::Get()->NotifyLoadLinked_Locked(addr,
2851 &global_monitor_thread_);
2856 printf_instr(
"SC_W\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2857 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2859 addr = si14_se + rj();
2860 if (!ProbeMemory(addr,
sizeof(int32_t)))
return;
2862 WriteConditionalW(addr,
static_cast<int32_t>(rd()), instr_.instr(),
2864 set_register(rd_reg(), LLbit);
2868 printf_instr(
"LL_D\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2869 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2871 addr = si14_se + rj();
2872 if (!ProbeMemory(addr,
sizeof(int64_t)))
return;
2874 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
2875 set_register(rd_reg(), Read2W(addr, instr_.instr()));
2876 local_monitor_.NotifyLoadLinked(addr, TransactionSize::DoubleWord);
2877 GlobalMonitor::Get()->NotifyLoadLinked_Locked(addr,
2878 &global_monitor_thread_);
2883 printf_instr(
"SC_D\t %s: %016lx, %s: %016lx, si14: %016lx\n",
2884 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2886 addr = si14_se + rj();
2887 if (!ProbeMemory(addr,
sizeof(int64_t)))
return;
2889 WriteConditional2W(addr, rd(), instr_.instr(), &LLbit);
2890 set_register(rd_reg(), LLbit);
2898void Simulator::DecodeTypeOp10() {
2899 int64_t alu_out = 0x0;
2900 int64_t si12_se = (
static_cast<int64_t
>(si12()) << 52) >> 52;
2901 uint64_t si12_ze = (
static_cast<uint64_t
>(ui12()) << 52) >> 52;
2903 switch (instr_.Bits(31, 22) << 22) {
2906 uint8_t lsbw_ = lsbw();
2907 uint8_t msbw_ = msbw();
2909 uint8_t size = msbw_ - lsbw_ + 1;
2910 uint64_t
mask = (1ULL <<
size) - 1;
2911 if (instr_.Bit(15) == 0) {
2914 "BSTRINS_W\t %s: %016lx, %s: %016lx, msbw: %02x, lsbw: %02x\n",
2915 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()), rj(),
2917 alu_out =
static_cast<int32_t>((rd_u() & ~(
mask << lsbw_)) |
2918 ((rj_u() &
mask) << lsbw_));
2922 "BSTRPICK_W\t %s: %016lx, %s: %016lx, msbw: %02x, lsbw: %02x\n",
2923 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()), rj(),
2927 SetResult(rd_reg(), alu_out);
2931 uint8_t lsbd_ = lsbd();
2932 uint8_t msbd_ = msbd();
2935 "BSTRINS_D\t %s: %016lx, %s: %016lx, msbw: %02x, lsbw: %02x\n",
2936 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()), rj(),
2938 uint8_t size = msbd_ - lsbd_ + 1;
2940 uint64_t
mask = (1ULL <<
size) - 1;
2941 alu_out = (rd_u() & ~(
mask << lsbd_)) | ((rj_u() &
mask) << lsbd_);
2942 SetResult(rd_reg(), alu_out);
2943 }
else if (size == 64) {
2944 SetResult(rd_reg(), rj());
2949 uint8_t lsbd_ = lsbd();
2950 uint8_t msbd_ = msbd();
2953 "BSTRPICK_D\t %s: %016lx, %s: %016lx, msbw: %02x, lsbw: %02x\n",
2954 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()), rj(),
2956 uint8_t size = msbd_ - lsbd_ + 1;
2958 uint64_t
mask = (1ULL <<
size) - 1;
2960 SetResult(rd_reg(), alu_out);
2961 }
else if (size == 64) {
2962 SetResult(rd_reg(), rj());
2967 printf_instr(
"SLTI\t %s: %016lx, %s: %016lx, si12: %016lx\n",
2968 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2970 SetResult(rd_reg(), rj() < si12_se ? 1 : 0);
2973 printf_instr(
"SLTUI\t %s: %016lx, %s: %016lx, si12: %016lx\n",
2974 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2976 SetResult(rd_reg(), rj_u() <
static_cast<uint64_t
>(si12_se) ? 1 : 0);
2979 printf_instr(
"ADDI_W\t %s: %016lx, %s: %016lx, si12: %016lx\n",
2980 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2984 SetResult(rd_reg(), alu32_out);
2988 printf_instr(
"ADDI_D\t %s: %016lx, %s: %016lx, si12: %016lx\n",
2989 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2991 SetResult(rd_reg(), rj() + si12_se);
2994 printf_instr(
"LU52I_D\t %s: %016lx, %s: %016lx, si12: %016lx\n",
2995 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
2997 int64_t si12_se =
static_cast<int64_t
>(si12()) << 52;
2998 uint64_t
mask = (1ULL << 52) - 1;
2999 alu_out = si12_se + (rj() &
mask);
3000 SetResult(rd_reg(), alu_out);
3004 printf_instr(
"ANDI\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3005 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3007 SetResult(rd_reg(), rj() & si12_ze);
3010 printf_instr(
"ORI\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3011 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3013 SetResult(rd_reg(), rj_u() | si12_ze);
3016 printf_instr(
"XORI\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3017 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3019 SetResult(rd_reg(), rj_u() ^ si12_ze);
3022 printf_instr(
"LD_B\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3023 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3025 if (!ProbeMemory(rj() + si12_se,
sizeof(int8_t)))
return;
3026 set_register(rd_reg(), ReadB(rj() + si12_se));
3029 printf_instr(
"LD_H\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3030 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3032 if (!ProbeMemory(rj() + si12_se,
sizeof(int16_t)))
return;
3033 set_register(rd_reg(), ReadH(rj() + si12_se, instr_.instr()));
3036 printf_instr(
"LD_W\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3037 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3039 if (!ProbeMemory(rj() + si12_se,
sizeof(int32_t)))
return;
3040 set_register(rd_reg(), ReadW(rj() + si12_se, instr_.instr()));
3043 printf_instr(
"LD_D\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3044 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3046 if (!ProbeMemory(rj() + si12_se,
sizeof(int64_t)))
return;
3047 set_register(rd_reg(), Read2W(rj() + si12_se, instr_.instr()));
3050 printf_instr(
"ST_B\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3051 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3053 if (!ProbeMemory(rj() + si12_se,
sizeof(int8_t)))
return;
3054 WriteB(rj() + si12_se,
static_cast<int8_t
>(rd()));
3057 printf_instr(
"ST_H\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3058 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3060 if (!ProbeMemory(rj() + si12_se,
sizeof(int16_t)))
return;
3061 WriteH(rj() + si12_se,
static_cast<int16_t>(rd()), instr_.instr());
3064 printf_instr(
"ST_W\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3065 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3067 if (!ProbeMemory(rj() + si12_se,
sizeof(int32_t)))
return;
3068 WriteW(rj() + si12_se,
static_cast<int32_t>(rd()), instr_.instr());
3071 printf_instr(
"ST_D\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3072 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3074 if (!ProbeMemory(rj() + si12_se,
sizeof(int64_t)))
return;
3075 Write2W(rj() + si12_se, rd(), instr_.instr());
3078 printf_instr(
"LD_BU\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3079 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3081 if (!ProbeMemory(rj() + si12_se,
sizeof(uint8_t)))
return;
3082 set_register(rd_reg(), ReadBU(rj() + si12_se));
3085 printf_instr(
"LD_HU\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3086 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3088 if (!ProbeMemory(rj() + si12_se,
sizeof(uint16_t)))
return;
3089 set_register(rd_reg(), ReadHU(rj() + si12_se, instr_.instr()));
3092 printf_instr(
"LD_WU\t %s: %016lx, %s: %016lx, si12: %016lx\n",
3093 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3095 if (!ProbeMemory(rj() + si12_se,
sizeof(uint32_t)))
return;
3096 set_register(rd_reg(), ReadWU(rj() + si12_se, instr_.instr()));
3099 printf_instr(
"FLD_S\t %s: %016f, %s: %016lx, si12: %016lx\n",
3100 FPURegisters::Name(fd_reg()), fd_float(),
3101 Registers::Name(rj_reg()), rj(), si12_ze);
3102 if (!ProbeMemory(rj() + si12_se,
sizeof(
float)))
return;
3103 set_fpu_register(fd_reg(), kFPUInvalidResult);
3104 set_fpu_register_word(
3105 fd_reg(), ReadW(rj() + si12_se, instr_.instr(), FLOAT_DOUBLE));
3109 printf_instr(
"FST_S\t %s: %016f, %s: %016lx, si12: %016lx\n",
3110 FPURegisters::Name(fd_reg()), fd_float(),
3111 Registers::Name(rj_reg()), rj(), si12_ze);
3112 if (!ProbeMemory(rj() + si12_se,
sizeof(
float)))
return;
3113 int32_t alu_out_32 =
static_cast<int32_t>(get_fpu_register(fd_reg()));
3114 WriteW(rj() + si12_se, alu_out_32, instr_.instr());
3118 printf_instr(
"FLD_D\t %s: %016f, %s: %016lx, si12: %016lx\n",
3119 FPURegisters::Name(fd_reg()), fd_double(),
3120 Registers::Name(rj_reg()), rj(), si12_ze);
3121 if (!ProbeMemory(rj() + si12_se,
sizeof(
double)))
return;
3122 set_fpu_register_double(fd_reg(), ReadD(rj() + si12_se, instr_.instr()));
3123 TraceMemRd(rj() + si12_se, get_fpu_register(fd_reg()), DOUBLE);
3127 printf_instr(
"FST_D\t %s: %016f, %s: %016lx, si12: %016lx\n",
3128 FPURegisters::Name(fd_reg()), fd_double(),
3129 Registers::Name(rj_reg()), rj(), si12_ze);
3130 if (!ProbeMemory(rj() + si12_se,
sizeof(
double)))
return;
3131 WriteD(rj() + si12_se, get_fpu_register_double(fd_reg()), instr_.instr());
3132 TraceMemWr(rj() + si12_se, get_fpu_register(fd_reg()),
DWORD);
3140void Simulator::DecodeTypeOp12() {
3141 switch (instr_.Bits(31, 20) << 20) {
3143 printf_instr(
"FMADD_S\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3144 FPURegisters::Name(fd_reg()), fd_float(),
3145 FPURegisters::Name(fk_reg()), fk_float(),
3146 FPURegisters::Name(fa_reg()), fa_float(),
3147 FPURegisters::Name(fj_reg()), fj_float());
3148 SetFPUFloatResult(fd_reg(), std::fma(fj_float(), fk_float(), fa_float()));
3151 printf_instr(
"FMADD_D\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3152 FPURegisters::Name(fd_reg()), fd_double(),
3153 FPURegisters::Name(fk_reg()), fk_double(),
3154 FPURegisters::Name(fa_reg()), fa_double(),
3155 FPURegisters::Name(fj_reg()), fj_double());
3156 SetFPUDoubleResult(fd_reg(),
3157 std::fma(fj_double(), fk_double(), fa_double()));
3160 printf_instr(
"FMSUB_S\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3161 FPURegisters::Name(fd_reg()), fd_float(),
3162 FPURegisters::Name(fk_reg()), fk_float(),
3163 FPURegisters::Name(fa_reg()), fa_float(),
3164 FPURegisters::Name(fj_reg()), fj_float());
3165 SetFPUFloatResult(fd_reg(),
3166 std::fma(fj_float(), fk_float(), -fa_float()));
3169 printf_instr(
"FMSUB_D\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3170 FPURegisters::Name(fd_reg()), fd_double(),
3171 FPURegisters::Name(fk_reg()), fk_double(),
3172 FPURegisters::Name(fa_reg()), fa_double(),
3173 FPURegisters::Name(fj_reg()), fj_double());
3174 SetFPUDoubleResult(fd_reg(),
3175 std::fma(fj_double(), fk_double(), -fa_double()));
3178 printf_instr(
"FNMADD_S\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3179 FPURegisters::Name(fd_reg()), fd_float(),
3180 FPURegisters::Name(fk_reg()), fk_float(),
3181 FPURegisters::Name(fa_reg()), fa_float(),
3182 FPURegisters::Name(fj_reg()), fj_float());
3183 SetFPUFloatResult(fd_reg(),
3184 std::fma(-fj_float(), fk_float(), -fa_float()));
3187 printf_instr(
"FNMADD_D\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3188 FPURegisters::Name(fd_reg()), fd_double(),
3189 FPURegisters::Name(fk_reg()), fk_double(),
3190 FPURegisters::Name(fa_reg()), fa_double(),
3191 FPURegisters::Name(fj_reg()), fj_double());
3192 SetFPUDoubleResult(fd_reg(),
3193 std::fma(-fj_double(), fk_double(), -fa_double()));
3196 printf_instr(
"FNMSUB_S\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3197 FPURegisters::Name(fd_reg()), fd_float(),
3198 FPURegisters::Name(fk_reg()), fk_float(),
3199 FPURegisters::Name(fa_reg()), fa_float(),
3200 FPURegisters::Name(fj_reg()), fj_float());
3201 SetFPUFloatResult(fd_reg(),
3202 std::fma(-fj_float(), fk_float(), fa_float()));
3205 printf_instr(
"FNMSUB_D\t %s: %016f, %s: %016f, %s: %016f %s: %016f\n",
3206 FPURegisters::Name(fd_reg()), fd_double(),
3207 FPURegisters::Name(fk_reg()), fk_double(),
3208 FPURegisters::Name(fa_reg()), fa_double(),
3209 FPURegisters::Name(fj_reg()), fj_double());
3210 SetFPUDoubleResult(fd_reg(),
3211 std::fma(-fj_double(), fk_double(), fa_double()));
3215 float fj = fj_float();
3216 float fk = fk_float();
3219 printf_instr(
"FCMP_CAF_S fcc%d\n", cd_reg());
3220 set_cf_register(cd_reg(),
false);
3224 printf_instr(
"FCMP_CUN_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3225 FPURegisters::Name(fj_reg()), fj,
3226 FPURegisters::Name(fk_reg()), fk);
3227 set_cf_register(cd_reg(), std::isnan(fj) || std::isnan(fk));
3231 printf_instr(
"FCMP_CEQ_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3232 FPURegisters::Name(fj_reg()), fj,
3233 FPURegisters::Name(fk_reg()), fk);
3234 set_cf_register(cd_reg(), fj == fk);
3238 printf_instr(
"FCMP_CUEQ_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3239 FPURegisters::Name(fj_reg()), fj,
3240 FPURegisters::Name(fk_reg()), fk);
3241 set_cf_register(cd_reg(),
3242 (fj == fk) || std::isnan(fj) || std::isnan(fk));
3246 printf_instr(
"FCMP_CLT_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3247 FPURegisters::Name(fj_reg()), fj,
3248 FPURegisters::Name(fk_reg()), fk);
3249 set_cf_register(cd_reg(), fj < fk);
3253 printf_instr(
"FCMP_CULT_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3254 FPURegisters::Name(fj_reg()), fj,
3255 FPURegisters::Name(fk_reg()), fk);
3256 set_cf_register(cd_reg(),
3257 (fj < fk) || std::isnan(fj) || std::isnan(fk));
3261 printf_instr(
"FCMP_CLE_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3262 FPURegisters::Name(fj_reg()), fj,
3263 FPURegisters::Name(fk_reg()), fk);
3264 set_cf_register(cd_reg(), fj <= fk);
3268 printf_instr(
"FCMP_CULE_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3269 FPURegisters::Name(fj_reg()), fj,
3270 FPURegisters::Name(fk_reg()), fk);
3271 set_cf_register(cd_reg(),
3272 (fj <= fk) || std::isnan(fj) || std::isnan(fk));
3276 printf_instr(
"FCMP_CNE_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3277 FPURegisters::Name(fj_reg()), fj,
3278 FPURegisters::Name(fk_reg()), fk);
3279 set_cf_register(cd_reg(), (fj < fk) || (fj > fk));
3283 printf_instr(
"FCMP_COR_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3284 FPURegisters::Name(fj_reg()), fj,
3285 FPURegisters::Name(fk_reg()), fk);
3286 set_cf_register(cd_reg(), !std::isnan(fj) && !std::isnan(fk));
3290 printf_instr(
"FCMP_CUNE_S fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3291 FPURegisters::Name(fj_reg()), fj,
3292 FPURegisters::Name(fk_reg()), fk);
3293 set_cf_register(cd_reg(),
3294 (fj != fk) || std::isnan(fj) || std::isnan(fk));
3316 double fj = fj_double();
3317 double fk = fk_double();
3320 printf_instr(
"FCMP_CAF_D fcc%d\n", cd_reg());
3321 set_cf_register(cd_reg(),
false);
3325 printf_instr(
"FCMP_CUN_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3326 FPURegisters::Name(fj_reg()), fj,
3327 FPURegisters::Name(fk_reg()), fk);
3328 set_cf_register(cd_reg(), std::isnan(fj) || std::isnan(fk));
3332 printf_instr(
"FCMP_CEQ_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3333 FPURegisters::Name(fj_reg()), fj,
3334 FPURegisters::Name(fk_reg()), fk);
3335 set_cf_register(cd_reg(), fj == fk);
3339 printf_instr(
"FCMP_CUEQ_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3340 FPURegisters::Name(fj_reg()), fj,
3341 FPURegisters::Name(fk_reg()), fk);
3342 set_cf_register(cd_reg(),
3343 (fj == fk) || std::isnan(fj) || std::isnan(fk));
3347 printf_instr(
"FCMP_CLT_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3348 FPURegisters::Name(fj_reg()), fj,
3349 FPURegisters::Name(fk_reg()), fk);
3350 set_cf_register(cd_reg(), fj < fk);
3354 printf_instr(
"FCMP_CULT_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3355 FPURegisters::Name(fj_reg()), fj,
3356 FPURegisters::Name(fk_reg()), fk);
3357 set_cf_register(cd_reg(),
3358 (fj < fk) || std::isnan(fj) || std::isnan(fk));
3362 printf_instr(
"FCMP_CLE_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3363 FPURegisters::Name(fj_reg()), fj,
3364 FPURegisters::Name(fk_reg()), fk);
3365 set_cf_register(cd_reg(), fj <= fk);
3369 printf_instr(
"FCMP_CULE_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3370 FPURegisters::Name(fj_reg()), fj,
3371 FPURegisters::Name(fk_reg()), fk);
3372 set_cf_register(cd_reg(),
3373 (fj <= fk) || std::isnan(fj) || std::isnan(fk));
3377 printf_instr(
"FCMP_CNE_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3378 FPURegisters::Name(fj_reg()), fj,
3379 FPURegisters::Name(fk_reg()), fk);
3380 set_cf_register(cd_reg(), (fj < fk) || (fj > fk));
3384 printf_instr(
"FCMP_COR_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3385 FPURegisters::Name(fj_reg()), fj,
3386 FPURegisters::Name(fk_reg()), fk);
3387 set_cf_register(cd_reg(), !std::isnan(fj) && !std::isnan(fk));
3391 printf_instr(
"FCMP_CUNE_D fcc%d, %s: %016f, %s: %016f\n", cd_reg(),
3392 FPURegisters::Name(fj_reg()), fj,
3393 FPURegisters::Name(fk_reg()), fk);
3394 set_cf_register(cd_reg(),
3395 (fj != fk) || std::isnan(fj) || std::isnan(fk));
3417 printf_instr(
"FSEL fcc%d, %s: %016f, %s: %016f, %s: %016f\n", ca_reg(),
3418 FPURegisters::Name(fd_reg()), fd_double(),
3419 FPURegisters::Name(fj_reg()), fj_double(),
3420 FPURegisters::Name(fk_reg()), fk_double());
3422 SetFPUDoubleResult(fd_reg(), fj_double());
3424 SetFPUDoubleResult(fd_reg(), fk_double());
3433void Simulator::DecodeTypeOp14() {
3434 int64_t alu_out = 0x0;
3437 switch (instr_.Bits(31, 18) << 18) {
3439 uint8_t sa = sa2() + 1;
3442 if (instr_.Bit(17) == 0) {
3444 printf_instr(
"ALSL_W\t %s: %016lx, %s: %016lx, %s: %016lx, sa2: %d\n",
3445 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3446 rj(), Registers::Name(rk_reg()), rk(), sa2());
3447 SetResult(rd_reg(), alu32_out);
3450 printf_instr(
"ALSL_WU\t %s: %016lx, %s: %016lx, %s: %016lx, sa2: %d\n",
3451 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3452 rj(), Registers::Name(rk_reg()), rk(), sa2());
3453 SetResult(rd_reg(),
static_cast<uint32_t
>(alu32_out));
3459 printf_instr(
"BYTEPICK_W\t %s: %016lx, %s: %016lx, %s: %016lx, sa2: %d\n",
3460 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3461 rj(), Registers::Name(rk_reg()), rk(), sa2());
3462 uint8_t sa = sa2() * 8;
3464 alu32_out =
static_cast<int32_t>(rk());
3468 int32_t rj_lo = (
static_cast<uint32_t
>(rj()) &
mask) >> (32 - sa);
3469 alu32_out = rk_hi | rj_lo;
3471 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3475 printf_instr(
"BYTEPICK_D\t %s: %016lx, %s: %016lx, %s: %016lx, sa3: %d\n",
3476 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3477 rj(), Registers::Name(rk_reg()), rk(), sa3());
3478 uint8_t sa = sa3() * 8;
3482 int64_t
mask = (1LL << 63) >> (sa - 1);
3483 int64_t rk_hi = (rk() & (~mask)) << sa;
3484 int64_t rj_lo =
static_cast<uint64_t
>(rj() &
mask) >> (64 - sa);
3485 alu_out = rk_hi | rj_lo;
3487 SetResult(rd_reg(), alu_out);
3491 printf_instr(
"ALSL_D\t %s: %016lx, %s: %016lx, %s: %016lx, sa2: %d\n",
3492 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3493 rj(), Registers::Name(rk_reg()), rk(), sa2());
3495 uint8_t sa = sa2() + 1;
3496 alu_out = (rj() << sa) + rk();
3497 SetResult(rd_reg(), alu_out);
3502 if (instr_.Bits(17, 15) == 0b001) {
3504 printf_instr(
"SLLI_W\t %s: %016lx, %s: %016lx, ui5: %d\n",
3505 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3507 alu32_out =
static_cast<int32_t>(rj()) << ui5();
3508 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3509 }
else if ((instr_.Bits(17, 16) == 0b01)) {
3511 printf_instr(
"SLLI_D\t %s: %016lx, %s: %016lx, ui6: %d\n",
3512 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3514 SetResult(rd_reg(), rj() << ui6());
3520 if (instr_.Bits(17, 15) == 0b001) {
3522 printf_instr(
"SRLI_W\t %s: %016lx, %s: %016lx, ui5: %d\n",
3523 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3525 alu32_out =
static_cast<uint32_t
>(rj()) >> ui5();
3526 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3527 }
else if (instr_.Bits(17, 16) == 0b01) {
3529 printf_instr(
"SRLI_D\t %s: %016lx, %s: %016lx, ui6: %d\n",
3530 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3532 SetResult(rd_reg(), rj_u() >> ui6());
3538 if (instr_.Bits(17, 15) == 0b001) {
3540 printf_instr(
"SRAI_W\t %s: %016lx, %s: %016lx, ui5: %d\n",
3541 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3543 alu32_out =
static_cast<int32_t>(rj()) >> ui5();
3544 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3545 }
else if (instr_.Bits(17, 16) == 0b01) {
3547 printf_instr(
"SRAI_D\t %s: %016lx, %s: %016lx, ui6: %d\n",
3548 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3550 SetResult(rd_reg(), rj() >> ui6());
3556 if (instr_.Bits(17, 15) == 0b001) {
3558 printf_instr(
"ROTRI_W\t %s: %016lx, %s: %016lx, ui5: %d\n",
3559 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3561 alu32_out =
static_cast<int32_t>(
3562 base::bits::RotateRight32(
static_cast<const uint32_t
>(rj_u()),
3563 static_cast<const uint32_t
>(ui5())));
3564 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3565 }
else if (instr_.Bits(17, 16) == 0b01) {
3567 printf_instr(
"ROTRI_D\t %s: %016lx, %s: %016lx, ui6: %d\n",
3568 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3571 static_cast<int64_t
>(base::bits::RotateRight64(rj_u(), ui6()));
3572 SetResult(rd_reg(), alu_out);
3573 printf_instr(
"ROTRI, %s, %s, %d\n", Registers::Name(rd_reg()),
3574 Registers::Name(rj_reg()), ui6());
3583void Simulator::DecodeTypeOp17() {
3586 switch (instr_.Bits(31, 15) << 15) {
3588 printf_instr(
"ADD_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3589 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3590 rj(), Registers::Name(rk_reg()), rk());
3593 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3597 printf_instr(
"ADD_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3598 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3599 rj(), Registers::Name(rk_reg()), rk());
3600 SetResult(rd_reg(), rj() + rk());
3603 printf_instr(
"SUB_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3604 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3605 rj(), Registers::Name(rk_reg()), rk());
3608 SetResult(rd_reg(),
static_cast<int64_t
>(alu32_out));
3612 printf_instr(
"SUB_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3613 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3614 rj(), Registers::Name(rk_reg()), rk());
3615 SetResult(rd_reg(), rj() - rk());
3618 printf_instr(
"SLT\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3619 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3620 rj(), Registers::Name(rk_reg()), rk());
3621 SetResult(rd_reg(), rj() < rk() ? 1 : 0);
3624 printf_instr(
"SLTU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3625 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3626 rj(), Registers::Name(rk_reg()), rk());
3627 SetResult(rd_reg(), rj_u() < rk_u() ? 1 : 0);
3630 printf_instr(
"MASKEQZ\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3631 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3632 rj(), Registers::Name(rk_reg()), rk());
3633 SetResult(rd_reg(), rk() == 0 ? 0 : rj());
3636 printf_instr(
"MASKNEZ\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3637 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3638 rj(), Registers::Name(rk_reg()), rk());
3639 SetResult(rd_reg(), rk() != 0 ? 0 : rj());
3642 printf_instr(
"NOR\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3643 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3644 rj(), Registers::Name(rk_reg()), rk());
3645 SetResult(rd_reg(), ~(rj() | rk()));
3648 printf_instr(
"AND\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3649 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3650 rj(), Registers::Name(rk_reg()), rk());
3651 SetResult(rd_reg(), rj() & rk());
3654 printf_instr(
"OR\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3655 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3656 rj(), Registers::Name(rk_reg()), rk());
3657 SetResult(rd_reg(), rj() | rk());
3660 printf_instr(
"XOR\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3661 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3662 rj(), Registers::Name(rk_reg()), rk());
3663 SetResult(rd_reg(), rj() ^ rk());
3666 printf_instr(
"ORN\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3667 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3668 rj(), Registers::Name(rk_reg()), rk());
3669 SetResult(rd_reg(), rj() | (~rk()));
3672 printf_instr(
"ANDN\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3673 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3674 rj(), Registers::Name(rk_reg()), rk());
3675 SetResult(rd_reg(), rj() & (~rk()));
3678 printf_instr(
"SLL_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3679 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3680 rj(), Registers::Name(rk_reg()), rk());
3681 SetResult(rd_reg(), (int32_t)rj() << (rk_u() % 32));
3684 printf_instr(
"SRL_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3685 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3686 rj(), Registers::Name(rk_reg()), rk());
3687 alu_out =
static_cast<int32_t>((uint32_t)rj_u() >> (rk_u() % 32));
3688 SetResult(rd_reg(), alu_out);
3692 printf_instr(
"SRA_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3693 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3694 rj(), Registers::Name(rk_reg()), rk());
3695 SetResult(rd_reg(), (int32_t)rj() >> (rk_u() % 32));
3698 printf_instr(
"SLL_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3699 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3700 rj(), Registers::Name(rk_reg()), rk());
3701 SetResult(rd_reg(), rj() << (rk_u() % 64));
3704 printf_instr(
"SRL_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3705 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3706 rj(), Registers::Name(rk_reg()), rk());
3707 alu_out =
static_cast<int64_t
>(rj_u() >> (rk_u() % 64));
3708 SetResult(rd_reg(), alu_out);
3712 printf_instr(
"SRA_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3713 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3714 rj(), Registers::Name(rk_reg()), rk());
3715 SetResult(rd_reg(), rj() >> (rk_u() % 64));
3718 printf_instr(
"ROTR_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3719 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3720 rj(), Registers::Name(rk_reg()), rk());
3721 alu_out =
static_cast<int32_t>(
3722 base::bits::RotateRight32(
static_cast<const uint32_t
>(rj_u()),
3723 static_cast<const uint32_t
>(rk_u() % 32)));
3724 SetResult(rd_reg(), alu_out);
3728 printf_instr(
"ROTR_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3729 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3730 rj(), Registers::Name(rk_reg()), rk());
3731 alu_out =
static_cast<int64_t
>(
3732 base::bits::RotateRight64((rj_u()), (rk_u() % 64)));
3733 SetResult(rd_reg(), alu_out);
3737 printf_instr(
"MUL_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3738 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3739 rj(), Registers::Name(rk_reg()), rk());
3740 alu_out =
static_cast<int32_t>(rj()) *
static_cast<int32_t>(rk());
3741 SetResult(rd_reg(), alu_out);
3745 printf_instr(
"MULH_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3746 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3747 rj(), Registers::Name(rk_reg()), rk());
3750 alu_out =
static_cast<int64_t
>(rj_lo) *
static_cast<int64_t
>(rk_lo);
3751 SetResult(rd_reg(), alu_out >> 32);
3755 printf_instr(
"MULH_WU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3756 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3757 rj(), Registers::Name(rk_reg()), rk());
3758 uint32_t rj_lo =
static_cast<uint32_t
>(rj_u());
3759 uint32_t rk_lo =
static_cast<uint32_t
>(rk_u());
3760 alu_out =
static_cast<uint64_t
>(rj_lo) *
static_cast<uint64_t
>(rk_lo);
3761 SetResult(rd_reg(), alu_out >> 32);
3765 printf_instr(
"MUL_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3766 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3767 rj(), Registers::Name(rk_reg()), rk());
3768 SetResult(rd_reg(), rj() * rk());
3771 printf_instr(
"MULH_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3772 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3773 rj(), Registers::Name(rk_reg()), rk());
3774 SetResult(rd_reg(), base::bits::SignedMulHigh64(rj(), rk()));
3777 printf_instr(
"MULH_DU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3778 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3779 rj(), Registers::Name(rk_reg()), rk());
3780 SetResult(rd_reg(), base::bits::UnsignedMulHigh64(rj_u(), rk_u()));
3783 printf_instr(
"MULW_D_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3784 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3785 rj(), Registers::Name(rk_reg()), rk());
3786 int64_t rj_i32 =
static_cast<int32_t>(rj());
3787 int64_t rk_i32 =
static_cast<int32_t>(rk());
3788 SetResult(rd_reg(), rj_i32 * rk_i32);
3792 printf_instr(
"MULW_D_WU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3793 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3794 rj(), Registers::Name(rk_reg()), rk());
3795 uint64_t rj_u32 =
static_cast<uint32_t
>(rj_u());
3796 uint64_t rk_u32 =
static_cast<uint32_t
>(rk_u());
3797 SetResult(rd_reg(), rj_u32 * rk_u32);
3801 printf_instr(
"DIV_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3802 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3803 rj(), Registers::Name(rk_reg()), rk());
3806 if (rj_i32 == INT_MIN && rk_i32 == -1) {
3807 SetResult(rd_reg(), INT_MIN);
3808 }
else if (rk_i32 != 0) {
3809 SetResult(rd_reg(), rj_i32 / rk_i32);
3814 printf_instr(
"MOD_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3815 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3816 rj(), Registers::Name(rk_reg()), rk());
3819 if (rj_i32 == INT_MIN && rk_i32 == -1) {
3820 SetResult(rd_reg(), 0);
3821 }
else if (rk_i32 != 0) {
3822 SetResult(rd_reg(), rj_i32 % rk_i32);
3827 printf_instr(
"DIV_WU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3828 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3829 rj(), Registers::Name(rk_reg()), rk());
3830 uint32_t rj_u32 =
static_cast<uint32_t
>(rj());
3831 uint32_t rk_u32 =
static_cast<uint32_t
>(rk());
3833 SetResult(rd_reg(),
static_cast<int32_t>(rj_u32 / rk_u32));
3838 printf_instr(
"MOD_WU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3839 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3840 rj(), Registers::Name(rk_reg()), rk());
3841 uint32_t rj_u32 =
static_cast<uint32_t
>(rj());
3842 uint32_t rk_u32 =
static_cast<uint32_t
>(rk());
3844 SetResult(rd_reg(),
static_cast<int32_t>(rj_u32 % rk_u32));
3849 printf_instr(
"DIV_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3850 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3851 rj(), Registers::Name(rk_reg()), rk());
3852 if (rj() == LONG_MIN && rk() == -1) {
3853 SetResult(rd_reg(), LONG_MIN);
3854 }
else if (rk() != 0) {
3855 SetResult(rd_reg(), rj() / rk());
3860 printf_instr(
"MOD_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3861 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3862 rj(), Registers::Name(rk_reg()), rk());
3863 if (rj() == LONG_MIN && rk() == -1) {
3864 SetResult(rd_reg(), 0);
3865 }
else if (rk() != 0) {
3866 SetResult(rd_reg(), rj() % rk());
3871 printf_instr(
"DIV_DU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3872 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3873 rj(), Registers::Name(rk_reg()), rk());
3875 SetResult(rd_reg(),
static_cast<int64_t
>(rj_u() / rk_u()));
3880 printf_instr(
"MOD_DU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
3881 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
3882 rj(), Registers::Name(rk_reg()), rk());
3884 SetResult(rd_reg(),
static_cast<int64_t
>(rj_u() % rk_u()));
3889 printf_instr(
"BREAK\t code: %x\n", instr_.Bits(14, 0));
3890 SoftwareInterrupt();
3893 printf_instr(
"FADD_S\t %s: %016f, %s, %016f, %s, %016f\n",
3894 FPURegisters::Name(fd_reg()), fd_float(),
3895 FPURegisters::Name(fj_reg()), fj_float(),
3896 FPURegisters::Name(fk_reg()), fk_float());
3899 FPUCanonalizeOperation([](
float lhs,
float rhs) {
return lhs + rhs; },
3900 fj_float(), fk_float()));
3904 printf_instr(
"FADD_D\t %s: %016f, %s, %016f, %s, %016f\n",
3905 FPURegisters::Name(fd_reg()), fd_double(),
3906 FPURegisters::Name(fj_reg()), fj_double(),
3907 FPURegisters::Name(fk_reg()), fk_double());
3908 SetFPUDoubleResult(fd_reg(),
3909 FPUCanonalizeOperation(
3910 [](
double lhs,
double rhs) {
return lhs + rhs; },
3911 fj_double(), fk_double()));
3915 printf_instr(
"FSUB_S\t %s: %016f, %s, %016f, %s, %016f\n",
3916 FPURegisters::Name(fd_reg()), fd_float(),
3917 FPURegisters::Name(fj_reg()), fj_float(),
3918 FPURegisters::Name(fk_reg()), fk_float());
3919 SetFPUFloatResult(fd_reg(), fj_float() - fk_float());
3923 printf_instr(
"FSUB_D\t %s: %016f, %s, %016f, %s, %016f\n",
3924 FPURegisters::Name(fd_reg()), fd_double(),
3925 FPURegisters::Name(fj_reg()), fj_double(),
3926 FPURegisters::Name(fk_reg()), fk_double());
3927 SetFPUDoubleResult(fd_reg(), fj_double() - fk_double());
3931 printf_instr(
"FMUL_S\t %s: %016f, %s, %016f, %s, %016f\n",
3932 FPURegisters::Name(fd_reg()), fd_float(),
3933 FPURegisters::Name(fj_reg()), fj_float(),
3934 FPURegisters::Name(fk_reg()), fk_float());
3937 FPUCanonalizeOperation([](
float lhs,
float rhs) {
return lhs * rhs; },
3938 fj_float(), fk_float()));
3942 printf_instr(
"FMUL_D\t %s: %016f, %s, %016f, %s, %016f\n",
3943 FPURegisters::Name(fd_reg()), fd_double(),
3944 FPURegisters::Name(fj_reg()), fj_double(),
3945 FPURegisters::Name(fk_reg()), fk_double());
3946 SetFPUDoubleResult(fd_reg(),
3947 FPUCanonalizeOperation(
3948 [](
double lhs,
double rhs) {
return lhs * rhs; },
3949 fj_double(), fk_double()));
3953 printf_instr(
"FDIV_S\t %s: %016f, %s, %016f, %s, %016f\n",
3954 FPURegisters::Name(fd_reg()), fd_float(),
3955 FPURegisters::Name(fj_reg()), fj_float(),
3956 FPURegisters::Name(fk_reg()), fk_float());
3959 FPUCanonalizeOperation([](
float lhs,
float rhs) {
return lhs / rhs; },
3960 fj_float(), fk_float()));
3964 printf_instr(
"FDIV_D\t %s: %016f, %s, %016f, %s, %016f\n",
3965 FPURegisters::Name(fd_reg()), fd_double(),
3966 FPURegisters::Name(fj_reg()), fj_double(),
3967 FPURegisters::Name(fk_reg()), fk_double());
3968 SetFPUDoubleResult(fd_reg(),
3969 FPUCanonalizeOperation(
3970 [](
double lhs,
double rhs) {
return lhs / rhs; },
3971 fj_double(), fk_double()));
3975 printf_instr(
"FMAX_S\t %s: %016f, %s, %016f, %s, %016f\n",
3976 FPURegisters::Name(fd_reg()), fd_float(),
3977 FPURegisters::Name(fj_reg()), fj_float(),
3978 FPURegisters::Name(fk_reg()), fk_float());
3979 SetFPUFloatResult(fd_reg(), FPUMax(fk_float(), fj_float()));
3982 printf_instr(
"FMAX_D\t %s: %016f, %s, %016f, %s, %016f\n",
3983 FPURegisters::Name(fd_reg()), fd_double(),
3984 FPURegisters::Name(fj_reg()), fj_double(),
3985 FPURegisters::Name(fk_reg()), fk_double());
3986 SetFPUDoubleResult(fd_reg(), FPUMax(fk_double(), fj_double()));
3989 printf_instr(
"FMIN_S\t %s: %016f, %s, %016f, %s, %016f\n",
3990 FPURegisters::Name(fd_reg()), fd_float(),
3991 FPURegisters::Name(fj_reg()), fj_float(),
3992 FPURegisters::Name(fk_reg()), fk_float());
3993 SetFPUFloatResult(fd_reg(), FPUMin(fk_float(), fj_float()));
3996 printf_instr(
"FMIN_D\t %s: %016f, %s, %016f, %s, %016f\n",
3997 FPURegisters::Name(fd_reg()), fd_double(),
3998 FPURegisters::Name(fj_reg()), fj_double(),
3999 FPURegisters::Name(fk_reg()), fk_double());
4000 SetFPUDoubleResult(fd_reg(), FPUMin(fk_double(), fj_double()));
4003 printf_instr(
"FMAXA_S\t %s: %016f, %s, %016f, %s, %016f\n",
4004 FPURegisters::Name(fd_reg()), fd_float(),
4005 FPURegisters::Name(fj_reg()), fj_float(),
4006 FPURegisters::Name(fk_reg()), fk_float());
4007 SetFPUFloatResult(fd_reg(), FPUMaxA(fk_float(), fj_float()));
4010 printf_instr(
"FMAXA_D\t %s: %016f, %s, %016f, %s, %016f\n",
4011 FPURegisters::Name(fd_reg()), fd_double(),
4012 FPURegisters::Name(fj_reg()), fj_double(),
4013 FPURegisters::Name(fk_reg()), fk_double());
4014 SetFPUDoubleResult(fd_reg(), FPUMaxA(fk_double(), fj_double()));
4017 printf_instr(
"FMINA_S\t %s: %016f, %s, %016f, %s, %016f\n",
4018 FPURegisters::Name(fd_reg()), fd_float(),
4019 FPURegisters::Name(fj_reg()), fj_float(),
4020 FPURegisters::Name(fk_reg()), fk_float());
4021 SetFPUFloatResult(fd_reg(), FPUMinA(fk_float(), fj_float()));
4024 printf_instr(
"FMINA_D\t %s: %016f, %s, %016f, %s, %016f\n",
4025 FPURegisters::Name(fd_reg()), fd_double(),
4026 FPURegisters::Name(fj_reg()), fj_double(),
4027 FPURegisters::Name(fk_reg()), fk_double());
4028 SetFPUDoubleResult(fd_reg(), FPUMinA(fk_double(), fj_double()));
4031 printf_instr(
"LDX_B\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4032 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4033 rj(), Registers::Name(rk_reg()), rk());
4034 if (!ProbeMemory(rj() + rk(),
sizeof(int8_t)))
return;
4035 set_register(rd_reg(), ReadB(rj() + rk()));
4038 printf_instr(
"LDX_H\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4039 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4040 rj(), Registers::Name(rk_reg()), rk());
4041 if (!ProbeMemory(rj() + rk(),
sizeof(int16_t)))
return;
4042 set_register(rd_reg(), ReadH(rj() + rk(), instr_.instr()));
4045 printf_instr(
"LDX_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4046 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4047 rj(), Registers::Name(rk_reg()), rk());
4048 if (!ProbeMemory(rj() + rk(),
sizeof(int32_t)))
return;
4049 set_register(rd_reg(), ReadW(rj() + rk(), instr_.instr()));
4052 printf_instr(
"LDX_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4053 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4054 rj(), Registers::Name(rk_reg()), rk());
4055 if (!ProbeMemory(rj() + rk(),
sizeof(int64_t)))
return;
4056 set_register(rd_reg(), Read2W(rj() + rk(), instr_.instr()));
4059 printf_instr(
"STX_B\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4060 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4061 rj(), Registers::Name(rk_reg()), rk());
4062 if (!ProbeMemory(rj() + rk(),
sizeof(int8_t)))
return;
4063 WriteB(rj() + rk(),
static_cast<int8_t
>(rd()));
4066 printf_instr(
"STX_H\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4067 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4068 rj(), Registers::Name(rk_reg()), rk());
4069 if (!ProbeMemory(rj() + rk(),
sizeof(int16_t)))
return;
4070 WriteH(rj() + rk(),
static_cast<int16_t>(rd()), instr_.instr());
4073 printf_instr(
"STX_W\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4074 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4075 rj(), Registers::Name(rk_reg()), rk());
4076 if (!ProbeMemory(rj() + rk(),
sizeof(int32_t)))
return;
4077 WriteW(rj() + rk(),
static_cast<int32_t>(rd()), instr_.instr());
4080 printf_instr(
"STX_D\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4081 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4082 rj(), Registers::Name(rk_reg()), rk());
4083 if (!ProbeMemory(rj() + rk(),
sizeof(int64_t)))
return;
4084 Write2W(rj() + rk(), rd(), instr_.instr());
4087 printf_instr(
"LDX_BU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4088 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4089 rj(), Registers::Name(rk_reg()), rk());
4090 if (!ProbeMemory(rj() + rk(),
sizeof(uint8_t)))
return;
4091 set_register(rd_reg(), ReadBU(rj() + rk()));
4094 printf_instr(
"LDX_HU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4095 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4096 rj(), Registers::Name(rk_reg()), rk());
4097 if (!ProbeMemory(rj() + rk(),
sizeof(uint16_t)))
return;
4098 set_register(rd_reg(), ReadHU(rj() + rk(), instr_.instr()));
4101 printf_instr(
"LDX_WU\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4102 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4103 rj(), Registers::Name(rk_reg()), rk());
4104 if (!ProbeMemory(rj() + rk(),
sizeof(uint32_t)))
return;
4105 set_register(rd_reg(), ReadWU(rj() + rk(), instr_.instr()));
4108 printf_instr(
"FLDX_S\t %s: %016f, %s: %016lx, %s: %016lx\n",
4109 FPURegisters::Name(fd_reg()), fd_float(),
4110 Registers::Name(rj_reg()), rj(), Registers::Name(rk_reg()),
4112 if (!ProbeMemory(rj() + rk(),
sizeof(
float)))
return;
4113 set_fpu_register(fd_reg(), kFPUInvalidResult);
4114 set_fpu_register_word(fd_reg(),
4115 ReadW(rj() + rk(), instr_.instr(), FLOAT_DOUBLE));
4118 printf_instr(
"FLDX_D\t %s: %016f, %s: %016lx, %s: %016lx\n",
4119 FPURegisters::Name(fd_reg()), fd_double(),
4120 Registers::Name(rj_reg()), rj(), Registers::Name(rk_reg()),
4122 if (!ProbeMemory(rj() + rk(),
sizeof(
double)))
return;
4123 set_fpu_register_double(fd_reg(), ReadD(rj() + rk(), instr_.instr()));
4126 printf_instr(
"FSTX_S\t %s: %016f, %s: %016lx, %s: %016lx\n",
4127 FPURegisters::Name(fd_reg()), fd_float(),
4128 Registers::Name(rj_reg()), rj(), Registers::Name(rk_reg()),
4130 if (!ProbeMemory(rj() + rk(),
sizeof(
float)))
return;
4131 WriteW(rj() + rk(),
static_cast<int32_t>(get_fpu_register(fd_reg())),
4135 printf_instr(
"FSTX_D\t %s: %016f, %s: %016lx, %s: %016lx\n",
4136 FPURegisters::Name(fd_reg()), fd_double(),
4137 Registers::Name(rj_reg()), rj(), Registers::Name(rk_reg()),
4139 if (!ProbeMemory(rj() + rk(),
sizeof(
double)))
return;
4140 WriteD(rj() + rk(), get_fpu_register_double(fd_reg()), instr_.instr());
4143 printf(
"Sim UNIMPLEMENTED: AMSWAP_W\n");
4146 printf(
"Sim UNIMPLEMENTED: AMSWAP_D\n");
4149 printf(
"Sim UNIMPLEMENTED: AMADD_W\n");
4152 printf(
"Sim UNIMPLEMENTED: AMADD_D\n");
4155 printf(
"Sim UNIMPLEMENTED: AMAND_W\n");
4158 printf(
"Sim UNIMPLEMENTED: AMAND_D\n");
4161 printf(
"Sim UNIMPLEMENTED: AMOR_W\n");
4164 printf(
"Sim UNIMPLEMENTED: AMOR_D\n");
4167 printf(
"Sim UNIMPLEMENTED: AMXOR_W\n");
4170 printf(
"Sim UNIMPLEMENTED: AMXOR_D\n");
4173 printf(
"Sim UNIMPLEMENTED: AMMAX_W\n");
4176 printf(
"Sim UNIMPLEMENTED: AMMAX_D\n");
4179 printf(
"Sim UNIMPLEMENTED: AMMIN_W\n");
4182 printf(
"Sim UNIMPLEMENTED: AMMIN_D\n");
4185 printf(
"Sim UNIMPLEMENTED: AMMAX_WU\n");
4188 printf(
"Sim UNIMPLEMENTED: AMMAX_DU\n");
4191 printf(
"Sim UNIMPLEMENTED: AMMIN_WU\n");
4194 printf(
"Sim UNIMPLEMENTED: AMMIN_DU\n");
4197 printf_instr(
"AMSWAP_DB_W:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4198 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4199 rk(), Registers::Name(rj_reg()), rj());
4200 if (!ProbeMemory(rj(),
sizeof(int32_t)))
return;
4204 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4205 set_register(rd_reg(), ReadW(rj(), instr_.instr()));
4206 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::Word);
4207 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4208 rj(), &global_monitor_thread_);
4210 WriteConditionalW(rj(),
static_cast<int32_t>(rk()), instr_.instr(),
4215 printf_instr(
"AMSWAP_DB_D:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4216 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4217 rk(), Registers::Name(rj_reg()), rj());
4218 if (!ProbeMemory(rj(),
sizeof(int64_t)))
return;
4222 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4223 set_register(rd_reg(), Read2W(rj(), instr_.instr()));
4224 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::DoubleWord);
4225 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4226 rj(), &global_monitor_thread_);
4228 WriteConditional2W(rj(), rk(), instr_.instr(), &success);
4232 printf_instr(
"AMADD_DB_W:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4233 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4234 rk(), Registers::Name(rj_reg()), rj());
4235 if (!ProbeMemory(rj(),
sizeof(int32_t)))
return;
4239 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4240 set_register(rd_reg(), ReadW(rj(), instr_.instr()));
4241 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::Word);
4242 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4243 rj(), &global_monitor_thread_);
4245 WriteConditionalW(rj(),
4248 instr_.instr(), &success);
4252 printf_instr(
"AMADD_DB_D:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4253 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4254 rk(), Registers::Name(rj_reg()), rj());
4255 if (!ProbeMemory(rj(),
sizeof(int64_t)))
return;
4259 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4260 set_register(rd_reg(), Read2W(rj(), instr_.instr()));
4261 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::DoubleWord);
4262 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4263 rj(), &global_monitor_thread_);
4265 WriteConditional2W(rj(), rk() + rd(), instr_.instr(), &success);
4269 printf_instr(
"AMAND_DB_W:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4270 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4271 rk(), Registers::Name(rj_reg()), rj());
4272 if (!ProbeMemory(rj(),
sizeof(int32_t)))
return;
4276 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4277 set_register(rd_reg(), ReadW(rj(), instr_.instr()));
4278 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::Word);
4279 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4280 rj(), &global_monitor_thread_);
4282 WriteConditionalW(rj(),
4285 instr_.instr(), &success);
4289 printf_instr(
"AMAND_DB_D:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4290 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4291 rk(), Registers::Name(rj_reg()), rj());
4292 if (!ProbeMemory(rj(),
sizeof(int64_t)))
return;
4296 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4297 set_register(rd_reg(), Read2W(rj(), instr_.instr()));
4298 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::DoubleWord);
4299 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4300 rj(), &global_monitor_thread_);
4302 WriteConditional2W(rj(), rk() & rd(), instr_.instr(), &success);
4306 printf_instr(
"AMOR_DB_W:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4307 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4308 rk(), Registers::Name(rj_reg()), rj());
4309 if (!ProbeMemory(rj(),
sizeof(int32_t)))
return;
4313 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4314 set_register(rd_reg(), ReadW(rj(), instr_.instr()));
4315 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::Word);
4316 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4317 rj(), &global_monitor_thread_);
4319 WriteConditionalW(rj(),
4322 instr_.instr(), &success);
4326 printf_instr(
"AMOR_DB_D:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4327 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4328 rk(), Registers::Name(rj_reg()), rj());
4329 if (!ProbeMemory(rj(),
sizeof(int64_t)))
return;
4333 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4334 set_register(rd_reg(), Read2W(rj(), instr_.instr()));
4335 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::DoubleWord);
4336 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4337 rj(), &global_monitor_thread_);
4339 WriteConditional2W(rj(), rk() | rd(), instr_.instr(), &success);
4343 printf_instr(
"AMXOR_DB_W:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4344 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4345 rk(), Registers::Name(rj_reg()), rj());
4346 if (!ProbeMemory(rj(),
sizeof(int32_t)))
return;
4350 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4351 set_register(rd_reg(), ReadW(rj(), instr_.instr()));
4352 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::Word);
4353 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4354 rj(), &global_monitor_thread_);
4356 WriteConditionalW(rj(),
4359 instr_.instr(), &success);
4363 printf_instr(
"AMXOR_DB_D:\t %s: %016lx, %s, %016lx, %s, %016lx\n",
4364 Registers::Name(rd_reg()), rd(), Registers::Name(rk_reg()),
4365 rk(), Registers::Name(rj_reg()), rj());
4366 if (!ProbeMemory(rj(),
sizeof(int64_t)))
return;
4370 base::MutexGuard lock_guard(&GlobalMonitor::Get()->
mutex);
4371 set_register(rd_reg(), Read2W(rj(), instr_.instr()));
4372 local_monitor_.NotifyLoadLinked(rj(), TransactionSize::DoubleWord);
4373 GlobalMonitor::Get()->NotifyLoadLinked_Locked(
4374 rj(), &global_monitor_thread_);
4376 WriteConditional2W(rj(), rk() ^ rd(), instr_.instr(), &success);
4380 printf(
"Sim UNIMPLEMENTED: AMMAX_DB_W\n");
4383 printf(
"Sim UNIMPLEMENTED: AMMAX_DB_D\n");
4386 printf(
"Sim UNIMPLEMENTED: AMMIN_DB_W\n");
4389 printf(
"Sim UNIMPLEMENTED: AMMIN_DB_D\n");
4392 printf(
"Sim UNIMPLEMENTED: AMMAX_DB_WU\n");
4395 printf(
"Sim UNIMPLEMENTED: AMMAX_DB_DU\n");
4398 printf(
"Sim UNIMPLEMENTED: AMMIN_DB_WU\n");
4401 printf(
"Sim UNIMPLEMENTED: AMMIN_DB_DU\n");
4404 printf_instr(
"DBAR\n");
4407 printf(
"Sim UNIMPLEMENTED: IBAR\n");
4410 printf(
"Sim UNIMPLEMENTED: FSCALEB_S\n");
4413 printf(
"Sim UNIMPLEMENTED: FSCALEB_D\n");
4416 printf_instr(
"FCOPYSIGN_S\t %s: %016f, %s, %016f, %s, %016f\n",
4417 FPURegisters::Name(fd_reg()), fd_float(),
4418 FPURegisters::Name(fj_reg()), fj_float(),
4419 FPURegisters::Name(fk_reg()), fk_float());
4420 SetFPUFloatResult(fd_reg(), std::copysign(fj_float(), fk_float()));
4423 printf_instr(
"FCOPYSIGN_d\t %s: %016f, %s, %016f, %s, %016f\n",
4424 FPURegisters::Name(fd_reg()), fd_double(),
4425 FPURegisters::Name(fj_reg()), fj_double(),
4426 FPURegisters::Name(fk_reg()), fk_double());
4427 SetFPUDoubleResult(fd_reg(), std::copysign(fj_double(), fk_double()));
4434void Simulator::DecodeTypeOp22() {
4437 switch (instr_.Bits(31, 10) << 10) {
4439 printf_instr(
"CLZ_W\t %s: %016lx, %s, %016lx\n",
4440 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4442 alu_out = base::bits::CountLeadingZeros32(
static_cast<int32_t>(rj_u()));
4443 SetResult(rd_reg(), alu_out);
4447 printf_instr(
"CTZ_W\t %s: %016lx, %s, %016lx\n",
4448 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4450 alu_out = base::bits::CountTrailingZeros32(
static_cast<int32_t>(rj_u()));
4451 SetResult(rd_reg(), alu_out);
4455 printf_instr(
"CLZ_D\t %s: %016lx, %s, %016lx\n",
4456 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4458 alu_out = base::bits::CountLeadingZeros64(
static_cast<int64_t
>(rj_u()));
4459 SetResult(rd_reg(), alu_out);
4463 printf_instr(
"CTZ_D\t %s: %016lx, %s, %016lx\n",
4464 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4466 alu_out = base::bits::CountTrailingZeros64(
static_cast<int64_t
>(rj_u()));
4467 SetResult(rd_reg(), alu_out);
4471 printf_instr(
"REVB_2H\t %s: %016lx, %s, %016lx\n",
4472 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4474 uint32_t input =
static_cast<uint32_t
>(rj());
4475 uint64_t output = 0;
4477 uint32_t
mask = 0xFF000000;
4478 for (
int i = 0;
i < 4;
i++) {
4479 uint32_t tmp =
mask & input;
4485 output = output |
tmp;
4489 alu_out =
static_cast<int64_t
>(
static_cast<int32_t>(output));
4490 SetResult(rd_reg(), alu_out);
4494 printf_instr(
"REVB_4H\t %s: %016lx, %s, %016lx\n",
4495 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4497 uint64_t input = rj_u();
4498 uint64_t output = 0;
4500 uint64_t
mask = 0xFF00000000000000;
4501 for (
int i = 0;
i < 8;
i++) {
4502 uint64_t tmp =
mask & input;
4508 output = output |
tmp;
4512 alu_out =
static_cast<int64_t
>(output);
4513 SetResult(rd_reg(), alu_out);
4517 printf_instr(
"REVB_2W\t %s: %016lx, %s, %016lx\n",
4518 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4520 uint64_t input = rj_u();
4521 uint64_t output = 0;
4523 uint64_t
mask = 0xFF000000FF000000;
4524 for (
int i = 0;
i < 4;
i++) {
4525 uint64_t tmp =
mask & input;
4527 tmp = tmp >> (24 -
i * 16);
4529 tmp = tmp << (
i * 16 - 24);
4531 output = output |
tmp;
4535 alu_out =
static_cast<int64_t
>(output);
4536 SetResult(rd_reg(), alu_out);
4540 printf_instr(
"REVB_D\t %s: %016lx, %s, %016lx\n",
4541 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4543 uint64_t input = rj_u();
4544 uint64_t output = 0;
4546 uint64_t
mask = 0xFF00000000000000;
4547 for (
int i = 0;
i < 8;
i++) {
4548 uint64_t tmp =
mask & input;
4550 tmp = tmp >> (56 -
i * 16);
4552 tmp = tmp << (
i * 16 - 56);
4554 output = output |
tmp;
4558 alu_out =
static_cast<int64_t
>(output);
4559 SetResult(rd_reg(), alu_out);
4563 printf_instr(
"REVH_2W\t %s: %016lx, %s, %016lx\n",
4564 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4566 uint64_t input = rj_u();
4567 uint64_t output = 0;
4569 uint64_t
mask = 0xFFFF000000000000;
4570 for (
int i = 0;
i < 4;
i++) {
4571 uint64_t tmp =
mask & input;
4577 output = output |
tmp;
4581 alu_out =
static_cast<int64_t
>(output);
4582 SetResult(rd_reg(), alu_out);
4586 printf_instr(
"REVH_D\t %s: %016lx, %s, %016lx\n",
4587 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4589 uint64_t input = rj_u();
4590 uint64_t output = 0;
4592 uint64_t
mask = 0xFFFF000000000000;
4593 for (
int i = 0;
i < 4;
i++) {
4594 uint64_t tmp =
mask & input;
4596 tmp = tmp >> (48 -
i * 32);
4598 tmp = tmp << (
i * 32 - 48);
4600 output = output |
tmp;
4604 alu_out =
static_cast<int64_t
>(output);
4605 SetResult(rd_reg(), alu_out);
4609 printf_instr(
"BITREV_4B\t %s: %016lx, %s, %016lx\n",
4610 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4612 uint32_t input =
static_cast<uint32_t
>(rj());
4613 uint32_t output = 0;
4614 uint8_t i_byte, o_byte;
4617 for (
int i = 0;
i < 4;
i++) {
4618 output = output >> 8;
4619 i_byte = input & 0xFF;
4623 o_byte =
static_cast<uint8_t
>(((i_byte * 0x0802LU & 0x22110LU) |
4624 (i_byte * 0x8020LU & 0x88440LU)) *
4628 output = output | (
static_cast<uint32_t
>(o_byte << 24));
4632 alu_out =
static_cast<int64_t
>(
static_cast<int32_t>(output));
4633 SetResult(rd_reg(), alu_out);
4637 printf_instr(
"BITREV_8B\t %s: %016lx, %s, %016lx\n",
4638 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4640 uint64_t input = rj_u();
4641 uint64_t output = 0;
4642 uint8_t i_byte, o_byte;
4645 for (
int i = 0;
i < 8;
i++) {
4646 output = output >> 8;
4647 i_byte = input & 0xFF;
4651 o_byte =
static_cast<uint8_t
>(((i_byte * 0x0802LU & 0x22110LU) |
4652 (i_byte * 0x8020LU & 0x88440LU)) *
4656 output = output | (
static_cast<uint64_t
>(o_byte) << 56);
4660 alu_out =
static_cast<int64_t
>(output);
4661 SetResult(rd_reg(), alu_out);
4665 printf_instr(
"BITREV_W\t %s: %016lx, %s, %016lx\n",
4666 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4668 uint32_t input =
static_cast<uint32_t
>(rj());
4669 uint32_t output = 0;
4670 output = base::bits::ReverseBits(input);
4671 alu_out =
static_cast<int64_t
>(
static_cast<int32_t>(output));
4672 SetResult(rd_reg(), alu_out);
4676 printf_instr(
"BITREV_D\t %s: %016lx, %s, %016lx\n",
4677 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4679 alu_out =
static_cast<int64_t
>(base::bits::ReverseBits(rj_u()));
4680 SetResult(rd_reg(), alu_out);
4684 printf_instr(
"EXT_W_B\t %s: %016lx, %s, %016lx\n",
4685 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4687 uint8_t input =
static_cast<uint8_t
>(rj());
4688 alu_out =
static_cast<int64_t
>(
static_cast<int8_t
>(input));
4689 SetResult(rd_reg(), alu_out);
4693 printf_instr(
"EXT_W_H\t %s: %016lx, %s, %016lx\n",
4694 Registers::Name(rd_reg()), rd(), Registers::Name(rj_reg()),
4697 alu_out =
static_cast<int64_t
>(
static_cast<int16_t>(input));
4698 SetResult(rd_reg(), alu_out);
4702 printf_instr(
"FABS_S\t %s: %016f, %s, %016f\n",
4703 FPURegisters::Name(fd_reg()), fd_float(),
4704 FPURegisters::Name(fj_reg()), fj_float());
4705 SetFPUFloatResult(fd_reg(), std::abs(fj_float()));
4708 printf_instr(
"FABS_D\t %s: %016f, %s, %016f\n",
4709 FPURegisters::Name(fd_reg()), fd_double(),
4710 FPURegisters::Name(fj_reg()), fj_double());
4711 SetFPUDoubleResult(fd_reg(), std::abs(fj_double()));
4714 printf_instr(
"FNEG_S\t %s: %016f, %s, %016f\n",
4715 FPURegisters::Name(fd_reg()), fd_float(),
4716 FPURegisters::Name(fj_reg()), fj_float());
4717 SetFPUFloatResult(fd_reg(), -fj_float());
4720 printf_instr(
"FNEG_D\t %s: %016f, %s, %016f\n",
4721 FPURegisters::Name(fd_reg()), fd_double(),
4722 FPURegisters::Name(fj_reg()), fj_double());
4723 SetFPUDoubleResult(fd_reg(), -fj_double());
4726 printf_instr(
"FSQRT_S\t %s: %016f, %s, %016f\n",
4727 FPURegisters::Name(fd_reg()), fd_float(),
4728 FPURegisters::Name(fj_reg()), fj_float());
4729 if (fj_float() >= 0) {
4730 SetFPUFloatResult(fd_reg(), std::sqrt(fj_float()));
4731 set_fcsr_bit(kFCSRInvalidOpCauseBit,
false);
4733 SetFPUFloatResult(fd_reg(), std::sqrt(-1));
4734 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
4739 printf_instr(
"FSQRT_D\t %s: %016f, %s, %016f\n",
4740 FPURegisters::Name(fd_reg()), fd_double(),
4741 FPURegisters::Name(fj_reg()), fj_double());
4742 if (fj_double() >= 0) {
4743 SetFPUDoubleResult(fd_reg(), std::sqrt(fj_double()));
4744 set_fcsr_bit(kFCSRInvalidOpCauseBit,
false);
4746 SetFPUDoubleResult(fd_reg(), std::sqrt(-1));
4747 set_fcsr_bit(kFCSRInvalidOpCauseBit,
true);
4752 printf_instr(
"FMOV_S\t %s: %016f, %s, %016f\n",
4753 FPURegisters::Name(fd_reg()), fd_float(),
4754 FPURegisters::Name(fj_reg()), fj_float());
4755 SetFPUFloatResult(fd_reg(), fj_float());
4758 printf_instr(
"FMOV_D\t %s: %016f, %s, %016f\n",
4759 FPURegisters::Name(fd_reg()), fd_float(),
4760 FPURegisters::Name(fj_reg()), fj_float());
4761 SetFPUDoubleResult(fd_reg(), fj_double());
4764 printf_instr(
"MOVGR2FR_W\t %s: %016f, %s, %016lx\n",
4765 FPURegisters::Name(fd_reg()), fd_double(),
4766 Registers::Name(rj_reg()), rj());
4767 set_fpu_register_word(fd_reg(),
static_cast<int32_t>(rj()));
4768 TraceRegWr(get_fpu_register(fd_reg()), FLOAT_DOUBLE);
4772 printf_instr(
"MOVGR2FR_D\t %s: %016f, %s, %016lx\n",
4773 FPURegisters::Name(fd_reg()), fd_double(),
4774 Registers::Name(rj_reg()), rj());
4775 SetFPUResult2(fd_reg(), rj());
4778 printf_instr(
"MOVGR2FRH_W\t %s: %016f, %s, %016lx\n",
4779 FPURegisters::Name(fd_reg()), fd_double(),
4780 Registers::Name(rj_reg()), rj());
4781 set_fpu_register_hi_word(fd_reg(),
static_cast<int32_t>(rj()));
4782 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
4786 printf_instr(
"MOVFR2GR_S\t %s: %016lx, %s, %016f\n",
4787 Registers::Name(rd_reg()), rd(),
4788 FPURegisters::Name(fj_reg()), fj_float());
4789 set_register(rd_reg(),
4790 static_cast<int64_t
>(get_fpu_register_word(fj_reg())));
4791 TraceRegWr(get_register(rd_reg()), WORD_DWORD);
4795 printf_instr(
"MOVFR2GR_D\t %s: %016lx, %s, %016f\n",
4796 Registers::Name(rd_reg()), rd(),
4797 FPURegisters::Name(fj_reg()), fj_double());
4798 SetResult(rd_reg(), get_fpu_register(fj_reg()));
4801 printf_instr(
"MOVFRH2GR_S\t %s: %016lx, %s, %016f\n",
4802 Registers::Name(rd_reg()), rd(),
4803 FPURegisters::Name(fj_reg()), fj_double());
4804 SetResult(rd_reg(), get_fpu_register_hi_word(fj_reg()));
4807 printf_instr(
"MOVGR2FCSR\t fcsr: %016x, %s, %016lx\n", FCSR_,
4808 Registers::Name(rj_reg()), rj());
4811 FCSR_ =
static_cast<uint32_t
>(rj());
4816 printf_instr(
"MOVFCSR2GR\t %s, %016lx, FCSR: %016x\n",
4817 Registers::Name(rd_reg()), rd(), FCSR_);
4820 SetResult(rd_reg(), FCSR_);
4824 printf_instr(
"FCVT_S_D\t %s: %016f, %s, %016f\n",
4825 FPURegisters::Name(fd_reg()), fd_double(),
4826 FPURegisters::Name(fj_reg()), fj_double());
4827 SetFPUFloatResult(fd_reg(),
static_cast<float>(fj_double()));
4830 printf_instr(
"FCVT_D_S\t %s: %016f, %s, %016f\n",
4831 FPURegisters::Name(fd_reg()), fd_double(),
4832 FPURegisters::Name(fj_reg()), fj_float());
4833 SetFPUDoubleResult(fd_reg(),
static_cast<double>(fj_float()));
4836 printf_instr(
"FTINTRM_W_S\t %s: %016f, %s, %016f\n",
4837 FPURegisters::Name(fd_reg()), fd_double(),
4838 FPURegisters::Name(fj_reg()), fj_float());
4839 float fj = fj_float();
4840 float rounded = floor(fj);
4842 SetFPUWordResult(fd_reg(),
result);
4843 if (set_fcsr_round_error(fj, rounded)) {
4844 set_fpu_register_word_invalid_result(fj, rounded);
4849 printf_instr(
"FTINTRM_W_D\t %s: %016f, %s, %016f\n",
4850 FPURegisters::Name(fd_reg()), fd_double(),
4851 FPURegisters::Name(fj_reg()), fj_double());
4852 double fj = fj_double();
4853 double rounded = floor(fj);
4855 SetFPUWordResult(fd_reg(),
result);
4856 if (set_fcsr_round_error(fj, rounded)) {
4857 set_fpu_register_invalid_result(fj, rounded);
4862 printf_instr(
"FTINTRM_L_S\t %s: %016f, %s, %016f\n",
4863 FPURegisters::Name(fd_reg()), fd_double(),
4864 FPURegisters::Name(fj_reg()), fj_float());
4865 float fj = fj_float();
4866 float rounded = floor(fj);
4867 int64_t
result =
static_cast<int64_t
>(rounded);
4868 SetFPUResult(fd_reg(),
result);
4869 if (set_fcsr_round64_error(fj, rounded)) {
4870 set_fpu_register_invalid_result64(fj, rounded);
4875 printf_instr(
"FTINTRM_L_D\t %s: %016f, %s, %016f\n",
4876 FPURegisters::Name(fd_reg()), fd_double(),
4877 FPURegisters::Name(fj_reg()), fj_double());
4878 double fj = fj_double();
4879 double rounded = floor(fj);
4880 int64_t
result =
static_cast<int64_t
>(rounded);
4881 SetFPUResult(fd_reg(),
result);
4882 if (set_fcsr_round64_error(fj, rounded)) {
4883 set_fpu_register_invalid_result64(fj, rounded);
4888 printf_instr(
"FTINTRP_W_S\t %s: %016f, %s, %016f\n",
4889 FPURegisters::Name(fd_reg()), fd_double(),
4890 FPURegisters::Name(fj_reg()), fj_float());
4891 float fj = fj_float();
4892 float rounded = ceil(fj);
4894 SetFPUWordResult(fd_reg(),
result);
4895 if (set_fcsr_round_error(fj, rounded)) {
4896 set_fpu_register_word_invalid_result(fj, rounded);
4901 printf_instr(
"FTINTRP_W_D\t %s: %016f, %s, %016f\n",
4902 FPURegisters::Name(fd_reg()), fd_double(),
4903 FPURegisters::Name(fj_reg()), fj_double());
4904 double fj = fj_double();
4905 double rounded = ceil(fj);
4907 SetFPUWordResult(fd_reg(),
result);
4908 if (set_fcsr_round_error(fj, rounded)) {
4909 set_fpu_register_invalid_result(fj, rounded);
4914 printf_instr(
"FTINTRP_L_S\t %s: %016f, %s, %016f\n",
4915 FPURegisters::Name(fd_reg()), fd_double(),
4916 FPURegisters::Name(fj_reg()), fj_float());
4917 float fj = fj_float();
4918 float rounded = ceil(fj);
4919 int64_t
result =
static_cast<int64_t
>(rounded);
4920 SetFPUResult(fd_reg(),
result);
4921 if (set_fcsr_round64_error(fj, rounded)) {
4922 set_fpu_register_invalid_result64(fj, rounded);
4927 printf_instr(
"FTINTRP_L_D\t %s: %016f, %s, %016f\n",
4928 FPURegisters::Name(fd_reg()), fd_double(),
4929 FPURegisters::Name(fj_reg()), fj_double());
4930 double fj = fj_double();
4931 double rounded = ceil(fj);
4932 int64_t
result =
static_cast<int64_t
>(rounded);
4933 SetFPUResult(fd_reg(),
result);
4934 if (set_fcsr_round64_error(fj, rounded)) {
4935 set_fpu_register_invalid_result64(fj, rounded);
4940 printf_instr(
"FTINTRZ_W_S\t %s: %016f, %s, %016f\n",
4941 FPURegisters::Name(fd_reg()), fd_double(),
4942 FPURegisters::Name(fj_reg()), fj_float());
4943 float fj = fj_float();
4944 float rounded = trunc(fj);
4946 SetFPUWordResult(fd_reg(),
result);
4947 if (set_fcsr_round_error(fj, rounded)) {
4948 set_fpu_register_word_invalid_result(fj, rounded);
4953 printf_instr(
"FTINTRZ_W_D\t %s: %016f, %s, %016f\n",
4954 FPURegisters::Name(fd_reg()), fd_double(),
4955 FPURegisters::Name(fj_reg()), fj_double());
4956 double fj = fj_double();
4957 double rounded = trunc(fj);
4959 SetFPUWordResult(fd_reg(),
result);
4960 if (set_fcsr_round_error(fj, rounded)) {
4961 set_fpu_register_invalid_result(fj, rounded);
4966 printf_instr(
"FTINTRZ_L_S\t %s: %016f, %s, %016f\n",
4967 FPURegisters::Name(fd_reg()), fd_double(),
4968 FPURegisters::Name(fj_reg()), fj_float());
4969 float fj = fj_float();
4970 float rounded = trunc(fj);
4971 int64_t
result =
static_cast<int64_t
>(rounded);
4972 SetFPUResult(fd_reg(),
result);
4973 if (set_fcsr_round64_error(fj, rounded)) {
4974 set_fpu_register_invalid_result64(fj, rounded);
4979 printf_instr(
"FTINTRZ_L_D\t %s: %016f, %s, %016f\n",
4980 FPURegisters::Name(fd_reg()), fd_double(),
4981 FPURegisters::Name(fj_reg()), fj_double());
4982 double fj = fj_double();
4983 double rounded = trunc(fj);
4984 int64_t
result =
static_cast<int64_t
>(rounded);
4985 SetFPUResult(fd_reg(),
result);
4986 if (set_fcsr_round64_error(fj, rounded)) {
4987 set_fpu_register_invalid_result64(fj, rounded);
4992 printf_instr(
"FTINTRNE_W_S\t %s: %016f, %s, %016f\n",
4993 FPURegisters::Name(fd_reg()), fd_double(),
4994 FPURegisters::Name(fj_reg()), fj_float());
4995 float fj = fj_float();
4996 float rounded = floor(fj + 0.5);
5003 SetFPUWordResult(fd_reg(),
result);
5004 if (set_fcsr_round_error(fj, rounded)) {
5005 set_fpu_register_word_invalid_result(fj, rounded);
5010 printf_instr(
"FTINTRNE_W_D\t %s: %016f, %s, %016f\n",
5011 FPURegisters::Name(fd_reg()), fd_double(),
5012 FPURegisters::Name(fj_reg()), fj_double());
5013 double fj = fj_double();
5014 double rounded = floor(fj + 0.5);
5021 SetFPUWordResult(fd_reg(),
result);
5022 if (set_fcsr_round_error(fj, rounded)) {
5023 set_fpu_register_invalid_result(fj, rounded);
5028 printf_instr(
"FTINTRNE_L_S\t %s: %016f, %s, %016f\n",
5029 FPURegisters::Name(fd_reg()), fd_double(),
5030 FPURegisters::Name(fj_reg()), fj_float());
5031 float fj = fj_float();
5032 float rounded = floor(fj + 0.5);
5033 int64_t
result =
static_cast<int64_t
>(rounded);
5039 SetFPUResult(fd_reg(),
result);
5040 if (set_fcsr_round64_error(fj, rounded)) {
5041 set_fpu_register_invalid_result64(fj, rounded);
5046 printf_instr(
"FTINTRNE_L_D\t %s: %016f, %s, %016f\n",
5047 FPURegisters::Name(fd_reg()), fd_double(),
5048 FPURegisters::Name(fj_reg()), fj_double());
5049 double fj = fj_double();
5050 double rounded = floor(fj + 0.5);
5051 int64_t
result =
static_cast<int64_t
>(rounded);
5057 SetFPUResult(fd_reg(),
result);
5058 if (set_fcsr_round64_error(fj, rounded)) {
5059 set_fpu_register_invalid_result64(fj, rounded);
5064 printf_instr(
"FTINT_W_S\t %s: %016f, %s, %016f\n",
5065 FPURegisters::Name(fd_reg()), fd_double(),
5066 FPURegisters::Name(fj_reg()), fj_float());
5067 float fj = fj_float();
5070 round_according_to_fcsr(fj, &rounded, &
result);
5071 SetFPUWordResult(fd_reg(),
result);
5072 if (set_fcsr_round_error(fj, rounded)) {
5073 set_fpu_register_word_invalid_result(fj, rounded);
5078 printf_instr(
"FTINT_W_D\t %s: %016f, %s, %016f\n",
5079 FPURegisters::Name(fd_reg()), fd_double(),
5080 FPURegisters::Name(fj_reg()), fj_double());
5081 double fj = fj_double();
5084 round_according_to_fcsr(fj, &rounded, &
result);
5085 SetFPUWordResult(fd_reg(),
result);
5086 if (set_fcsr_round_error(fj, rounded)) {
5087 set_fpu_register_word_invalid_result(fj, rounded);
5092 printf_instr(
"FTINT_L_S\t %s: %016f, %s, %016f\n",
5093 FPURegisters::Name(fd_reg()), fd_double(),
5094 FPURegisters::Name(fj_reg()), fj_float());
5095 float fj = fj_float();
5098 round64_according_to_fcsr(fj, &rounded, &
result);
5099 SetFPUResult(fd_reg(),
result);
5100 if (set_fcsr_round64_error(fj, rounded)) {
5101 set_fpu_register_invalid_result64(fj, rounded);
5106 printf_instr(
"FTINT_L_D\t %s: %016f, %s, %016f\n",
5107 FPURegisters::Name(fd_reg()), fd_double(),
5108 FPURegisters::Name(fj_reg()), fj_double());
5109 double fj = fj_double();
5112 round64_according_to_fcsr(fj, &rounded, &
result);
5113 SetFPUResult(fd_reg(),
result);
5114 if (set_fcsr_round64_error(fj, rounded)) {
5115 set_fpu_register_invalid_result64(fj, rounded);
5120 alu_out = get_fpu_register_signed_word(fj_reg());
5121 printf_instr(
"FFINT_S_W\t %s: %016f, %s, %016x\n",
5122 FPURegisters::Name(fd_reg()), fd_double(),
5123 FPURegisters::Name(fj_reg()),
static_cast<int>(alu_out));
5124 SetFPUFloatResult(fd_reg(),
static_cast<float>(alu_out));
5128 alu_out = get_fpu_register(fj_reg());
5129 printf_instr(
"FFINT_S_L\t %s: %016f, %s, %016lx\n",
5130 FPURegisters::Name(fd_reg()), fd_double(),
5131 FPURegisters::Name(fj_reg()), alu_out);
5132 SetFPUFloatResult(fd_reg(),
static_cast<float>(alu_out));
5136 alu_out = get_fpu_register_signed_word(fj_reg());
5137 printf_instr(
"FFINT_D_W\t %s: %016f, %s, %016x\n",
5138 FPURegisters::Name(fd_reg()), fd_double(),
5139 FPURegisters::Name(fj_reg()),
static_cast<int>(alu_out));
5140 SetFPUDoubleResult(fd_reg(),
static_cast<double>(alu_out));
5144 alu_out = get_fpu_register(fj_reg());
5145 printf_instr(
"FFINT_D_L\t %s: %016f, %s, %016lx\n",
5146 FPURegisters::Name(fd_reg()), fd_double(),
5147 FPURegisters::Name(fj_reg()), alu_out);
5148 SetFPUDoubleResult(fd_reg(),
static_cast<double>(alu_out));
5152 printf_instr(
"FRINT_S\t %s: %016f, %s, %016f mode : ",
5153 FPURegisters::Name(fd_reg()), fd_float(),
5154 FPURegisters::Name(fj_reg()), fj_float());
5155 float fj = fj_float();
5156 float result, temp_result;
5158 float upper = ceil(fj);
5159 float lower = floor(fj);
5160 switch (get_fcsr_rounding_mode()) {
5162 printf_instr(
" kRoundToNearest\n");
5163 if (upper - fj < fj - lower) {
5165 }
else if (upper - fj > fj - lower) {
5168 temp_result = upper / 2;
5169 float reminder = std::modf(temp_result, &temp);
5170 if (reminder == 0) {
5178 printf_instr(
" kRoundToZero\n");
5179 result = (fj > 0 ? lower : upper);
5182 printf_instr(
" kRoundToPlusInf\n");
5186 printf_instr(
" kRoundToMinusInf\n");
5190 SetFPUFloatResult(fd_reg(),
result);
5191 set_fcsr_bit(kFCSRInexactCauseBit,
result != fj);
5195 printf_instr(
"FRINT_D\t %s: %016f, %s, %016f mode : ",
5196 FPURegisters::Name(fd_reg()), fd_double(),
5197 FPURegisters::Name(fj_reg()), fj_double());
5198 double fj = fj_double();
5199 double result, temp, temp_result;
5200 double upper = ceil(fj);
5201 double lower = floor(fj);
5202 switch (get_fcsr_rounding_mode()) {
5204 printf_instr(
" kRoundToNearest\n");
5205 if (upper - fj < fj - lower) {
5207 }
else if (upper - fj > fj - lower) {
5210 temp_result = upper / 2;
5211 double reminder = std::modf(temp_result, &temp);
5212 if (reminder == 0) {
5220 printf_instr(
" kRoundToZero\n");
5221 result = (fj > 0 ? lower : upper);
5224 printf_instr(
" kRoundToPlusInf\n");
5228 printf_instr(
" kRoundToMinusInf\n");
5232 SetFPUDoubleResult(fd_reg(),
result);
5233 set_fcsr_bit(kFCSRInexactCauseBit,
result != fj);
5237 printf(
"Sim UNIMPLEMENTED: MOVFR2CF\n");
5240 printf(
"Sim UNIMPLEMENTED: MOVCF2FR\n");
5243 printf_instr(
"MOVGR2CF\t FCC%d, %s: %016lx\n", cd_reg(),
5244 Registers::Name(rj_reg()), rj());
5245 set_cf_register(cd_reg(), rj() & 1);
5248 printf_instr(
"MOVCF2GR\t %s: %016lx, FCC%d\n", Registers::Name(rd_reg()),
5250 SetResult(rd_reg(), cj());
5253 printf(
"Sim UNIMPLEMENTED: FRECIP_S\n");
5256 printf(
"Sim UNIMPLEMENTED: FRECIP_D\n");
5259 printf(
"Sim UNIMPLEMENTED: FRSQRT_S\n");
5262 printf(
"Sim UNIMPLEMENTED: FRSQRT_D\n");
5265 printf(
"Sim UNIMPLEMENTED: FCLASS_S\n");
5268 printf(
"Sim UNIMPLEMENTED: FCLASS_D\n");
5271 printf(
"Sim UNIMPLEMENTED: FLOGB_S\n");
5274 printf(
"Sim UNIMPLEMENTED: FLOGB_D\n");
5277 printf(
"Sim UNIMPLEMENTED: CLO_W\n");
5280 printf(
"Sim UNIMPLEMENTED: CTO_W\n");
5283 printf(
"Sim UNIMPLEMENTED: CLO_D\n");
5286 printf(
"Sim UNIMPLEMENTED: CTO_D\n");
5297void Simulator::InstructionDecode(Instruction*
instr) {
5299 CheckICache(i_cache(),
instr);
5301 pc_modified_ =
false;
5306 base::SNPrintF(trace_buf_,
" ");
5310 dasm.InstructionDecode(buffer,
reinterpret_cast<uint8_t*
>(
instr));
5313 static int instr_count = 0;
5316 printf_instr(
"\nInstr%3d: %08x, PC: %016lx\t", instr_count++,
5317 instr_.Bits(31, 0), get_pc());
5318 switch (instr_.InstructionType()) {
5319 case Instruction::kOp6Type:
5322 case Instruction::kOp7Type:
5325 case Instruction::kOp8Type:
5328 case Instruction::kOp10Type:
5331 case Instruction::kOp12Type:
5334 case Instruction::kOp14Type:
5337 case Instruction::kOp17Type:
5340 case Instruction::kOp22Type:
5344 printf(
"instr_: %x\n", instr_.Bits(31, 0));
5350 PrintF(
" 0x%08" PRIxPTR
" %-44s %s\n",
5351 reinterpret_cast<intptr_t
>(
instr), buffer.
begin(),
5352 trace_buf_.begin());
5355 if (!pc_modified_) {
5356 set_register(
pc,
reinterpret_cast<int64_t
>(
instr) + kInstrSize);
5360void Simulator::Execute() {
5363 int64_t program_counter = get_pc();
5367 while (program_counter != end_sim_pc) {
5368 Instruction*
instr =
reinterpret_cast<Instruction*
>(program_counter);
5370 InstructionDecode(
instr);
5371 program_counter = get_pc();
5376 while (program_counter != end_sim_pc) {
5377 Instruction*
instr =
reinterpret_cast<Instruction*
>(program_counter);
5379 if (icount_ ==
static_cast<int64_t
>(
v8_flags.stop_sim_at)) {
5380 Loong64Debugger dbg(
this);
5383 InstructionDecode(
instr);
5385 program_counter = get_pc();
5390void Simulator::CallInternal(Address entry) {
5392 isolate_->stack_guard()->AdjustStackLimitForSimulator();
5395 set_register(
pc,
static_cast<int64_t
>(entry));
5399 set_register(ra, end_sim_pc);
5402 int64_t s0_val = get_register(s0);
5403 int64_t s1_val = get_register(s1);
5404 int64_t s2_val = get_register(s2);
5405 int64_t s3_val = get_register(s3);
5406 int64_t s4_val = get_register(s4);
5407 int64_t s5_val = get_register(s5);
5408 int64_t s6_val = get_register(s6);
5409 int64_t s7_val = get_register(s7);
5410 int64_t s8_val = get_register(s8);
5411 int64_t gp_val = get_register(gp);
5412 int64_t sp_val = get_register(sp);
5413 int64_t tp_val = get_register(tp);
5414 int64_t fp_val = get_register(fp);
5418 int64_t callee_saved_value = icount_;
5419 set_register(s0, callee_saved_value);
5420 set_register(s1, callee_saved_value);
5421 set_register(s2, callee_saved_value);
5422 set_register(s3, callee_saved_value);
5423 set_register(s4, callee_saved_value);
5424 set_register(s5, callee_saved_value);
5425 set_register(s6, callee_saved_value);
5426 set_register(s7, callee_saved_value);
5427 set_register(s8, callee_saved_value);
5428 set_register(gp, callee_saved_value);
5429 set_register(tp, callee_saved_value);
5430 set_register(fp, callee_saved_value);
5436 CHECK_EQ(callee_saved_value, get_register(s0));
5437 CHECK_EQ(callee_saved_value, get_register(s1));
5438 CHECK_EQ(callee_saved_value, get_register(s2));
5439 CHECK_EQ(callee_saved_value, get_register(s3));
5440 CHECK_EQ(callee_saved_value, get_register(s4));
5441 CHECK_EQ(callee_saved_value, get_register(s5));
5442 CHECK_EQ(callee_saved_value, get_register(s6));
5443 CHECK_EQ(callee_saved_value, get_register(s7));
5444 CHECK_EQ(callee_saved_value, get_register(s8));
5445 CHECK_EQ(callee_saved_value, get_register(gp));
5446 CHECK_EQ(callee_saved_value, get_register(tp));
5447 CHECK_EQ(callee_saved_value, get_register(fp));
5450 set_register(s0, s0_val);
5451 set_register(s1, s1_val);
5452 set_register(s2, s2_val);
5453 set_register(s3, s3_val);
5454 set_register(s4, s4_val);
5455 set_register(s5, s5_val);
5456 set_register(s6, s6_val);
5457 set_register(s7, s7_val);
5458 set_register(s8, s8_val);
5459 set_register(gp, gp_val);
5460 set_register(sp, sp_val);
5461 set_register(tp, tp_val);
5462 set_register(fp, fp_val);
5465void Simulator::CallImpl(Address entry, CallArgument*
args) {
5469 std::vector<int64_t> stack_args(0);
5470 for (
int i = 0; !
args[
i].IsEnd();
i++) {
5471 CallArgument arg =
args[
i];
5472 if (arg.IsGP() && (index_gp < 8)) {
5473 set_register(index_gp + 4, arg.bits());
5475 }
else if (arg.IsFP() && (index_fp < 8)) {
5476 set_fpu_register(index_fp++, arg.bits());
5477 }
else if (arg.IsFP() && (index_gp < 8)) {
5478 set_register(index_gp + 4, arg.bits());
5481 DCHECK(arg.IsFP() || arg.IsGP());
5482 stack_args.push_back(arg.bits());
5487 int64_t original_stack = get_register(sp);
5489 int64_t stack_args_size = stack_args.size() *
sizeof(stack_args[0]);
5490 int64_t entry_stack = original_stack - stack_args_size;
5492 if (base::OS::ActivationFrameAlignment() != 0) {
5493 entry_stack &= -base::OS::ActivationFrameAlignment();
5496 char* stack_argument =
reinterpret_cast<char*
>(entry_stack);
5497 memcpy(stack_argument, stack_args.data(),
5498 stack_args.size() *
sizeof(int64_t));
5499 set_register(sp, entry_stack);
5501 CallInternal(entry);
5504 CHECK_EQ(entry_stack, get_register(sp));
5505 set_register(sp, original_stack);
5508double Simulator::CallFP(Address entry,
double d0,
double d1) {
5509 const FPURegister fparg2 = f1;
5510 set_fpu_register_double(f0, d0);
5511 set_fpu_register_double(fparg2, d1);
5512 CallInternal(entry);
5513 return get_fpu_register_double(f0);
5516uintptr_t Simulator::PushAddress(uintptr_t address) {
5517 int64_t new_sp = get_register(sp) -
sizeof(uintptr_t);
5518 uintptr_t* stack_slot =
reinterpret_cast<uintptr_t*
>(new_sp);
5519 *stack_slot = address;
5520 set_register(sp, new_sp);
5524uintptr_t Simulator::PopAddress() {
5525 int64_t current_sp = get_register(sp);
5526 uintptr_t* stack_slot =
reinterpret_cast<uintptr_t*
>(current_sp);
5527 uintptr_t address = *stack_slot;
5528 set_register(sp, current_sp +
sizeof(uintptr_t));
5532Simulator::LocalMonitor::LocalMonitor()
5533 : access_state_(MonitorAccess::Open),
5537void Simulator::LocalMonitor::Clear() {
5538 access_state_ = MonitorAccess::Open;
5540 size_ = TransactionSize::None;
5543void Simulator::LocalMonitor::NotifyLoad() {
5544 if (access_state_ == MonitorAccess::RMW) {
5551void Simulator::LocalMonitor::NotifyLoadLinked(uintptr_t addr,
5552 TransactionSize size) {
5553 access_state_ = MonitorAccess::RMW;
5554 tagged_addr_ = addr;
5558void Simulator::LocalMonitor::NotifyStore() {
5559 if (access_state_ == MonitorAccess::RMW) {
5566bool Simulator::LocalMonitor::NotifyStoreConditional(uintptr_t addr,
5567 TransactionSize size) {
5568 if (access_state_ == MonitorAccess::RMW) {
5569 if (addr == tagged_addr_ &&
size_ == size) {
5576 DCHECK(access_state_ == MonitorAccess::Open);
5581Simulator::GlobalMonitor::LinkedAddress::LinkedAddress()
5582 : access_state_(MonitorAccess::Open),
5586 failure_counter_(0) {}
5588void Simulator::GlobalMonitor::LinkedAddress::Clear_Locked() {
5589 access_state_ = MonitorAccess::Open;
5593void Simulator::GlobalMonitor::LinkedAddress::NotifyLoadLinked_Locked(
5595 access_state_ = MonitorAccess::RMW;
5596 tagged_addr_ = addr;
5599void Simulator::GlobalMonitor::LinkedAddress::NotifyStore_Locked() {
5600 if (access_state_ == MonitorAccess::RMW) {
5607bool Simulator::GlobalMonitor::LinkedAddress::NotifyStoreConditional_Locked(
5608 uintptr_t addr,
bool is_requesting_thread) {
5609 if (access_state_ == MonitorAccess::RMW) {
5610 if (is_requesting_thread) {
5611 if (addr == tagged_addr_) {
5616 if (failure_counter_++ >= kMaxFailureCounter) {
5617 failure_counter_ = 0;
5623 }
else if ((addr & kExclusiveTaggedAddrMask) ==
5624 (tagged_addr_ & kExclusiveTaggedAddrMask)) {
5635void Simulator::GlobalMonitor::NotifyLoadLinked_Locked(
5636 uintptr_t addr, LinkedAddress* linked_address) {
5637 linked_address->NotifyLoadLinked_Locked(addr);
5638 PrependProcessor_Locked(linked_address);
5641void Simulator::GlobalMonitor::NotifyStore_Locked(
5642 LinkedAddress* linked_address) {
5644 for (LinkedAddress* iter = head_; iter; iter = iter->next_) {
5645 iter->NotifyStore_Locked();
5649bool Simulator::GlobalMonitor::NotifyStoreConditional_Locked(
5650 uintptr_t addr, LinkedAddress* linked_address) {
5651 DCHECK(IsProcessorInLinkedList_Locked(linked_address));
5652 if (linked_address->NotifyStoreConditional_Locked(addr,
true)) {
5654 for (LinkedAddress* iter = head_; iter; iter = iter->next_) {
5655 if (iter != linked_address) {
5656 iter->NotifyStoreConditional_Locked(addr,
false);
5665bool Simulator::GlobalMonitor::IsProcessorInLinkedList_Locked(
5666 LinkedAddress* linked_address)
const {
5667 return head_ == linked_address || linked_address->next_ ||
5668 linked_address->prev_;
5671void Simulator::GlobalMonitor::PrependProcessor_Locked(
5672 LinkedAddress* linked_address) {
5673 if (IsProcessorInLinkedList_Locked(linked_address)) {
5678 head_->prev_ = linked_address;
5680 linked_address->prev_ =
nullptr;
5681 linked_address->next_ = head_;
5682 head_ = linked_address;
5685void Simulator::GlobalMonitor::RemoveLinkedAddress(
5686 LinkedAddress* linked_address) {
5687 base::MutexGuard lock_guard(&
mutex);
5688 if (!IsProcessorInLinkedList_Locked(linked_address)) {
5692 if (linked_address->prev_) {
5693 linked_address->prev_->next_ = linked_address->next_;
5695 head_ = linked_address->next_;
5697 if (linked_address->next_) {
5698 linked_address->next_->prev_ = linked_address->prev_;
5700 linked_address->prev_ =
nullptr;
5701 linked_address->next_ =
nullptr;
virtual void VisitPointer(const void *address)=0
TemplateHashMapEntry< void *, void * > Entry
constexpr T * begin() const
static const char * Name(int reg)
static int Number(const char *name)
Instr InstructionBits() const
int Bits(int hi, int lo) const
constexpr int8_t code() const
static int Number(const char *name)
static constexpr int ToInt(const Tagged< Object > object)
base::Vector< const DirectHandle< Object > > args
std::optional< TNode< JSArray > > a
ZoneVector< RpoNumber > & result
#define DEFINE_LAZY_LEAKY_OBJECT_GETTER(T, FunctionName,...)
CustomMatcherTemplateHashMapImpl< DefaultAllocationPolicy > CustomMatcherHashMap
void DeleteArray(T *array)
constexpr VFPRoundingMode kRoundToNearest
constexpr UnconditionalBranchOp BL
constexpr VFPRoundingMode kRoundToMinusInf
void PrintF(const char *format,...)
char * ReadLine(const char *prompt)
const Instr rtCallRedirInstr
constexpr uint32_t kMaxStopCode
const uint32_t kMaxWatchpointCode
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
const int kNumFPURegisters
const int kInvalidFPURegister
void Print(Tagged< Object > obj)
const int kNumSimuRegisters
constexpr VFPRoundingMode kRoundToPlusInf
const int kInvalidRegister
void ShortPrint(Tagged< Object > obj, FILE *out)
constexpr Register kWasmTrapHandlerFaultAddressRegister
V8_EXPORT_PRIVATE FlagValues v8_flags
const uint32_t kFPURoundingModeMask
constexpr VFPRoundingMode kRoundToZero
constexpr uint8_t kInstrSize
V8_WARN_UNUSED_RESULT bool IsValidHeapObject(Heap *heap, Tagged< HeapObject > object)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
base::SmallVector< RegisterT, kStaticCapacity > registers_
const uintptr_t stack_limit_
#define DCHECK_LE(v1, v2)
#define CHECK_LT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
std::unique_ptr< ValueMirror > value