12 #if V8_TARGET_ARCH_MIPS
23 #if defined(USE_SIMULATOR)
30 return ((a ^ b) >= 0);
53 explicit MipsDebugger(Simulator* sim) : sim_(sim) { }
56 void Stop(Instruction* instr);
60 void PrintAllRegsIncludingFPU();
65 static const Instr kNopInstr = 0x0;
69 int32_t GetRegisterValue(
int regnum);
70 int32_t GetFPURegisterValue32(
int regnum);
71 int64_t GetFPURegisterValue64(
int regnum);
72 float GetFPURegisterValueFloat(
int regnum);
73 double GetFPURegisterValueDouble(
int regnum);
74 bool GetValue(
const char* desc,
int32_t* value);
75 bool GetValue(
const char* desc, int64_t* value);
78 bool SetBreakpoint(Instruction* breakpc);
79 bool DeleteBreakpoint(Instruction* breakpc);
83 void UndoBreakpoints();
84 void RedoBreakpoints();
88 MipsDebugger::~MipsDebugger() {
92 #ifdef GENERATED_CODE_COVERAGE
93 static FILE* coverage_log =
NULL;
96 static void InitializeCoverage() {
97 char* file_name = getenv(
"V8_GENERATED_CODE_COVERAGE_LOG");
98 if (file_name !=
NULL) {
99 coverage_log = fopen(file_name,
"aw+");
104 void MipsDebugger::Stop(Instruction* instr) {
109 reinterpret_cast<char**
>(sim_->get_pc() + Instr::kInstrSize);
110 char* msg = *msg_address;
114 if (!watched_stops_[code].desc) {
115 watched_stops_[code].desc = msg;
118 if (strlen(msg) > 0) {
119 if (coverage_log !=
NULL) {
120 fprintf(coverage_log,
"%s\n", str);
121 fflush(coverage_log);
124 instr->SetInstructionBits(kNopInstr);
125 reinterpret_cast<Instr*
>(msg_address)->SetInstructionBits(kNopInstr);
133 #define UNSUPPORTED() printf("Unsupported instruction.\n");
135 static void InitializeCoverage() {}
138 void MipsDebugger::Stop(Instruction* instr) {
142 char* msg = *
reinterpret_cast<char**
>(sim_->get_pc() +
145 if (!sim_->watched_stops_[code].desc) {
146 sim_->watched_stops_[code].desc = msg;
148 PrintF(
"Simulator hit %s (%u)\n", msg, code);
155 int32_t MipsDebugger::GetRegisterValue(
int regnum) {
157 return sim_->get_pc();
159 return sim_->get_register(regnum);
164 int32_t MipsDebugger::GetFPURegisterValue32(
int regnum) {
166 return sim_->get_pc();
168 return sim_->get_fpu_register_word(regnum);
173 int64_t MipsDebugger::GetFPURegisterValue64(
int regnum) {
175 return sim_->get_pc();
177 return sim_->get_fpu_register(regnum);
182 float MipsDebugger::GetFPURegisterValueFloat(
int regnum) {
184 return sim_->get_pc();
186 return sim_->get_fpu_register_float(regnum);
191 double MipsDebugger::GetFPURegisterValueDouble(
int regnum) {
193 return sim_->get_pc();
195 return sim_->get_fpu_register_double(regnum);
200 bool MipsDebugger::GetValue(
const char* desc,
int32_t* value) {
205 *value = GetRegisterValue(regnum);
208 *value = GetFPURegisterValue32(fpuregnum);
210 }
else if (strncmp(desc,
"0x", 2) == 0) {
211 return SScanF(desc,
"%x",
reinterpret_cast<uint32_t*
>(value)) == 1;
213 return SScanF(desc,
"%i", value) == 1;
219 bool MipsDebugger::GetValue(
const char* desc, int64_t* value) {
224 *value = GetRegisterValue(regnum);
227 *value = GetFPURegisterValue64(fpuregnum);
229 }
else if (strncmp(desc,
"0x", 2) == 0) {
230 return SScanF(desc + 2,
"%" SCNx64,
231 reinterpret_cast<uint64_t*
>(value)) == 1;
233 return SScanF(desc,
"%" SCNu64,
reinterpret_cast<uint64_t*
>(value)) == 1;
239 bool MipsDebugger::SetBreakpoint(Instruction* breakpc) {
241 if (sim_->break_pc_ !=
NULL) {
246 sim_->break_pc_ = breakpc;
247 sim_->break_instr_ = breakpc->InstructionBits();
254 bool MipsDebugger::DeleteBreakpoint(Instruction* breakpc) {
255 if (sim_->break_pc_ !=
NULL) {
256 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
259 sim_->break_pc_ =
NULL;
260 sim_->break_instr_ = 0;
265 void MipsDebugger::UndoBreakpoints() {
266 if (sim_->break_pc_ !=
NULL) {
267 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
272 void MipsDebugger::RedoBreakpoints() {
273 if (sim_->break_pc_ !=
NULL) {
274 sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
279 void MipsDebugger::PrintAllRegs() {
280 #define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)
284 PrintF(
"%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
285 REG_INFO(1), REG_INFO(2), REG_INFO(4));
287 PrintF(
"%26s\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
288 "", REG_INFO(3), REG_INFO(5));
290 PrintF(
"%26s\t%26s\t%3s: 0x%08x %10d\n",
"",
"", REG_INFO(6));
292 PrintF(
"%26s\t%26s\t%3s: 0x%08x %10d\n",
"",
"", REG_INFO(7));
295 for (
int i = 0;
i < 8;
i++) {
296 PrintF(
"%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
297 REG_INFO(8+
i), REG_INFO(16+
i));
301 PrintF(
"%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
302 REG_INFO(24), REG_INFO(26), REG_INFO(32));
304 PrintF(
"%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
305 REG_INFO(25), REG_INFO(27), REG_INFO(33));
307 PrintF(
"%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
308 REG_INFO(29), REG_INFO(30), REG_INFO(28));
310 PrintF(
"%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
311 REG_INFO(31), REG_INFO(34));
318 void MipsDebugger::PrintAllRegsIncludingFPU() {
319 #define FPU_REG_INFO32(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \
320 GetFPURegisterValue32(n+1), \
321 GetFPURegisterValue32(n), \
322 GetFPURegisterValueDouble(n)
324 #define FPU_REG_INFO64(n) FPURegisters::Name(n), \
325 GetFPURegisterValue64(n), \
326 GetFPURegisterValueDouble(n)
335 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(0) );
336 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(1) );
337 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(2) );
338 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(3) );
339 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(4) );
340 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(5) );
341 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(6) );
342 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(7) );
343 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(8) );
344 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(9) );
345 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(10));
346 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(11));
347 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(12));
348 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(13));
349 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(14));
350 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(15));
351 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(16));
352 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(17));
353 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(18));
354 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(19));
355 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(20));
356 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(21));
357 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(22));
358 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(23));
359 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(24));
360 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(25));
361 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(26));
362 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(27));
363 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(28));
364 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(29));
365 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(30));
366 PrintF(
"%3s: 0x%016llx %16.4e\n", FPU_REG_INFO64(31));
368 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(0) );
369 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(2) );
370 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(4) );
371 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(6) );
372 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(8) );
373 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(10));
374 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(12));
375 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(14));
376 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(16));
377 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(18));
378 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(20));
379 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(22));
380 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(24));
381 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(26));
382 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(28));
383 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO32(30));
387 #undef FPU_REG_INFO32
388 #undef FPU_REG_INFO64
392 void MipsDebugger::Debug() {
393 intptr_t last_pc = -1;
396 #define COMMAND_SIZE 63
400 #define XSTR(a) STR(a)
402 char cmd[COMMAND_SIZE + 1];
403 char arg1[ARG_SIZE + 1];
404 char arg2[ARG_SIZE + 1];
405 char* argv[3] = { cmd, arg1, arg2 };
408 cmd[COMMAND_SIZE] = 0;
416 while (!done && (sim_->get_pc() != Simulator::end_sim_pc)) {
417 if (last_pc != sim_->get_pc()) {
422 dasm.InstructionDecode(buffer,
423 reinterpret_cast<byte*
>(sim_->get_pc()));
424 PrintF(
" 0x%08x %s\n", sim_->get_pc(), buffer.
start());
425 last_pc = sim_->get_pc();
431 char* last_input = sim_->last_debugger_input();
432 if (strcmp(line,
"\n") == 0 && last_input !=
NULL) {
436 sim_->set_last_debugger_input(line);
440 int argc = SScanF(line,
441 "%" XSTR(COMMAND_SIZE)
"s "
442 "%" XSTR(ARG_SIZE)
"s "
443 "%" XSTR(ARG_SIZE)
"s",
445 if ((strcmp(cmd,
"si") == 0) || (strcmp(cmd,
"stepi") == 0)) {
446 Instruction* instr =
reinterpret_cast<Instruction*
>(sim_->get_pc());
447 if (!(instr->IsTrap()) ||
449 sim_->InstructionDecode(
450 reinterpret_cast<Instruction*
>(sim_->get_pc()));
453 PrintF(
"/!\\ Jumping over generated breakpoint.\n");
456 }
else if ((strcmp(cmd,
"c") == 0) || (strcmp(cmd,
"cont") == 0)) {
458 sim_->InstructionDecode(
reinterpret_cast<Instruction*
>(sim_->get_pc()));
461 }
else if ((strcmp(cmd,
"p") == 0) || (strcmp(cmd,
"print") == 0)) {
463 if (strcmp(arg1,
"all") == 0) {
465 }
else if (strcmp(arg1,
"allf") == 0) {
466 PrintAllRegsIncludingFPU();
473 value = GetRegisterValue(regnum);
474 PrintF(
"%s: 0x%08x %d \n", arg1, value, value);
479 value = GetFPURegisterValue64(fpuregnum);
480 dvalue = GetFPURegisterValueDouble(fpuregnum);
481 PrintF(
"%3s: 0x%016llx %16.4e\n",
484 if (fpuregnum % 2 == 1) {
487 value = GetFPURegisterValue32(fpuregnum);
488 fvalue = GetFPURegisterValueFloat(fpuregnum);
489 PrintF(
"%s: 0x%08x %11.4e\n", arg1, value, fvalue);
492 int32_t lvalue1 = GetFPURegisterValue32(fpuregnum);
493 int32_t lvalue2 = GetFPURegisterValue32(fpuregnum + 1);
494 dfvalue = GetFPURegisterValueDouble(fpuregnum);
495 PrintF(
"%3s,%3s: 0x%08x%08x %16.4e\n",
504 PrintF(
"%s unrecognized\n", arg1);
509 if (strcmp(arg2,
"single") == 0) {
515 value = GetFPURegisterValue32(fpuregnum);
516 fvalue = GetFPURegisterValueFloat(fpuregnum);
517 PrintF(
"%s: 0x%08x %11.4e\n", arg1, value, fvalue);
519 PrintF(
"%s unrecognized\n", arg1);
522 PrintF(
"print <fpu register> single\n");
525 PrintF(
"print <register> or print <fpu register> single\n");
528 }
else if ((strcmp(cmd,
"po") == 0)
529 || (strcmp(cmd,
"printobject") == 0)) {
533 if (GetValue(arg1, &value)) {
535 os << arg1 <<
": \n";
540 os << Brief(obj) <<
"\n";
543 os << arg1 <<
" unrecognized\n";
546 PrintF(
"printobject <value>\n");
548 }
else if (strcmp(cmd,
"stack") == 0 || strcmp(cmd,
"mem") == 0) {
553 if (strcmp(cmd,
"stack") == 0) {
557 if (!GetValue(arg1, &value)) {
558 PrintF(
"%s unrecognized\n", arg1);
561 cur =
reinterpret_cast<int32_t*
>(value);
568 if (argc == next_arg) {
571 if (!GetValue(argv[next_arg], &words)) {
578 if (argc == next_arg) {
581 if (!GetValue(argv[next_arg], &words)) {
589 PrintF(
" 0x%08x: 0x%08x %10d",
590 reinterpret_cast<intptr_t
>(cur), *cur, *cur);
591 HeapObject* obj =
reinterpret_cast<HeapObject*
>(*cur);
593 Heap* current_heap = v8::internal::Isolate::Current()->heap();
594 if (((value & 1) == 0) || current_heap->Contains(obj)) {
596 if ((value & 1) == 0) {
597 PrintF(
"smi %d", value / 2);
607 }
else if ((strcmp(cmd,
"disasm") == 0) ||
608 (strcmp(cmd,
"dpc") == 0) ||
609 (strcmp(cmd,
"di") == 0)) {
619 cur =
reinterpret_cast<byte*
>(sim_->get_pc());
621 }
else if (argc == 2) {
626 if (GetValue(arg1, &value)) {
627 cur =
reinterpret_cast<byte*
>(value);
634 if (GetValue(arg1, &value)) {
635 cur =
reinterpret_cast<byte*
>(sim_->get_pc());
643 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
644 cur =
reinterpret_cast<byte*
>(value1);
650 dasm.InstructionDecode(buffer, cur);
652 reinterpret_cast<intptr_t
>(cur), buffer.
start());
655 }
else if (strcmp(cmd,
"gdb") == 0) {
656 PrintF(
"relinquishing control to gdb\n");
658 PrintF(
"regaining control from gdb\n");
659 }
else if (strcmp(cmd,
"break") == 0) {
662 if (GetValue(arg1, &value)) {
663 if (!SetBreakpoint(
reinterpret_cast<Instruction*
>(value))) {
664 PrintF(
"setting breakpoint failed\n");
667 PrintF(
"%s unrecognized\n", arg1);
670 PrintF(
"break <address>\n");
672 }
else if (strcmp(cmd,
"del") == 0) {
673 if (!DeleteBreakpoint(
NULL)) {
674 PrintF(
"deleting breakpoint failed\n");
676 }
else if (strcmp(cmd,
"flags") == 0) {
677 PrintF(
"No flags on MIPS !\n");
678 }
else if (strcmp(cmd,
"stop") == 0) {
680 intptr_t stop_pc = sim_->get_pc() -
682 Instruction* stop_instr =
reinterpret_cast<Instruction*
>(stop_pc);
683 Instruction* msg_address =
684 reinterpret_cast<Instruction*
>(stop_pc +
686 if ((argc == 2) && (strcmp(arg1,
"unstop") == 0)) {
688 if (sim_->IsStopInstruction(stop_instr)) {
689 stop_instr->SetInstructionBits(kNopInstr);
690 msg_address->SetInstructionBits(kNopInstr);
692 PrintF(
"Not at debugger stop.\n");
694 }
else if (argc == 3) {
696 if (strcmp(arg1,
"info") == 0) {
697 if (strcmp(arg2,
"all") == 0) {
698 PrintF(
"Stop information:\n");
702 sim_->PrintStopInfo(
i);
704 }
else if (GetValue(arg2, &value)) {
705 sim_->PrintStopInfo(value);
707 PrintF(
"Unrecognized argument.\n");
709 }
else if (strcmp(arg1,
"enable") == 0) {
711 if (strcmp(arg2,
"all") == 0) {
717 }
else if (GetValue(arg2, &value)) {
718 sim_->EnableStop(value);
720 PrintF(
"Unrecognized argument.\n");
722 }
else if (strcmp(arg1,
"disable") == 0) {
724 if (strcmp(arg2,
"all") == 0) {
728 sim_->DisableStop(
i);
730 }
else if (GetValue(arg2, &value)) {
731 sim_->DisableStop(value);
733 PrintF(
"Unrecognized argument.\n");
737 PrintF(
"Wrong usage. Use help command for more information.\n");
739 }
else if ((strcmp(cmd,
"stat") == 0) || (strcmp(cmd,
"st") == 0)) {
753 cur =
reinterpret_cast<byte*
>(sim_->get_pc());
755 }
else if (argc == 2) {
757 if (GetValue(arg1, &value)) {
758 cur =
reinterpret_cast<byte*
>(value);
765 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
766 cur =
reinterpret_cast<byte*
>(value1);
772 dasm.InstructionDecode(buffer, cur);
774 reinterpret_cast<intptr_t
>(cur), buffer.
start());
777 }
else if ((strcmp(cmd,
"h") == 0) || (strcmp(cmd,
"help") == 0)) {
779 PrintF(
" continue execution (alias 'c')\n");
781 PrintF(
" step one instruction (alias 'si')\n");
782 PrintF(
"print <register>\n");
783 PrintF(
" print register content (alias 'p')\n");
784 PrintF(
" use register name 'all' to print all registers\n");
785 PrintF(
"printobject <register>\n");
786 PrintF(
" print an object from a register (alias 'po')\n");
787 PrintF(
"stack [<words>]\n");
788 PrintF(
" dump stack content, default dump 10 words)\n");
789 PrintF(
"mem <address> [<words>]\n");
790 PrintF(
" dump memory content, default dump 10 words)\n");
793 PrintF(
"disasm [<instructions>]\n");
794 PrintF(
"disasm [<address/register>]\n");
795 PrintF(
"disasm [[<address/register>] <instructions>]\n");
796 PrintF(
" disassemble code, default is 10 instructions\n");
797 PrintF(
" from pc (alias 'di')\n");
800 PrintF(
"break <address>\n");
801 PrintF(
" set a break point on the address\n");
803 PrintF(
" delete the breakpoint\n");
804 PrintF(
"stop feature:\n");
805 PrintF(
" Description:\n");
806 PrintF(
" Stops are debug instructions inserted by\n");
807 PrintF(
" the Assembler::stop() function.\n");
808 PrintF(
" When hitting a stop, the Simulator will\n");
809 PrintF(
" stop and and give control to the Debugger.\n");
810 PrintF(
" All stop codes are watched:\n");
811 PrintF(
" - They can be enabled / disabled: the Simulator\n");
812 PrintF(
" will / won't stop when hitting them.\n");
813 PrintF(
" - The Simulator keeps track of how many times they \n");
814 PrintF(
" are met. (See the info command.) Going over a\n");
815 PrintF(
" disabled stop still increases its counter. \n");
817 PrintF(
" stop info all/<code> : print infos about number <code>\n");
818 PrintF(
" or all stop(s).\n");
819 PrintF(
" stop enable/disable all/<code> : enables / disables\n");
820 PrintF(
" all or number <code> stop(s)\n");
822 PrintF(
" ignore the stop instruction at the current location\n");
825 PrintF(
"Unknown command: %s\n", cmd);
842 static bool ICacheMatch(
void* one,
void* two) {
843 DCHECK((
reinterpret_cast<intptr_t
>(one) & CachePage::kPageMask) == 0);
844 DCHECK((
reinterpret_cast<intptr_t
>(two) & CachePage::kPageMask) == 0);
849 static uint32_t ICacheHash(
void* key) {
855 intptr_t start_page = (start & ~CachePage::kPageMask);
856 intptr_t end_page = ((start +
size) & ~CachePage::kPageMask);
857 return start_page == end_page;
861 void Simulator::set_last_debugger_input(
char* input) {
863 last_debugger_input_ = input;
870 intptr_t start =
reinterpret_cast<intptr_t
>(start_addr);
871 int intra_line = (start & CachePage::kLineMask);
874 size = ((
size - 1) | CachePage::kLineMask) + 1;
875 int offset = (start & CachePage::kPageMask);
876 while (!AllOnOnePage(start,
size - 1)) {
877 int bytes_to_flush = CachePage::kPageSize - offset;
878 FlushOnePage(i_cache, start, bytes_to_flush);
879 start += bytes_to_flush;
880 size -= bytes_to_flush;
881 DCHECK_EQ(0, start & CachePage::kPageMask);
885 FlushOnePage(i_cache, start,
size);
891 v8::internal::HashMap::Entry* entry = i_cache->
Lookup(page,
894 if (entry->value ==
NULL) {
895 CachePage* new_page =
new CachePage();
896 entry->value = new_page;
898 return reinterpret_cast<CachePage*
>(entry->value);
908 DCHECK((start & CachePage::kLineMask) == 0);
910 void* page =
reinterpret_cast<void*
>(start & (~CachePage::kPageMask));
911 int offset = (start & CachePage::kPageMask);
912 CachePage* cache_page = GetCachePage(i_cache, page);
913 char* valid_bytemap = cache_page->ValidityByte(offset);
914 memset(valid_bytemap, CachePage::LINE_INVALID,
size >> CachePage::kLineShift);
919 Instruction* instr) {
920 intptr_t address =
reinterpret_cast<intptr_t
>(instr);
921 void* page =
reinterpret_cast<void*
>(address & (~CachePage::kPageMask));
922 void* line =
reinterpret_cast<void*
>(address & (~CachePage::kLineMask));
923 int offset = (address & CachePage::kPageMask);
924 CachePage* cache_page = GetCachePage(i_cache, page);
925 char* cache_valid_byte = cache_page->ValidityByte(offset);
926 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
927 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
930 CHECK_EQ(0, memcmp(
reinterpret_cast<void*
>(instr),
931 cache_page->CachedData(offset),
935 memcpy(cached_line, line, CachePage::kLineLength);
936 *cache_valid_byte = CachePage::LINE_VALID;
941 void Simulator::Initialize(Isolate* isolate) {
942 if (isolate->simulator_initialized())
return;
943 isolate->set_simulator_initialized(
true);
944 ::v8::internal::ExternalReference::set_redirector(isolate,
945 &RedirectExternalReference);
949 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
950 i_cache_ = isolate_->simulator_i_cache();
951 if (i_cache_ ==
NULL) {
953 isolate_->set_simulator_i_cache(i_cache_);
958 stack_ =
reinterpret_cast<char*
>(malloc(stack_size_));
959 pc_modified_ =
false;
971 FPUregisters_[
i] = 0;
978 registers_[
sp] =
reinterpret_cast<int32_t>(stack_) + stack_size_ - 64;
981 registers_[
pc] = bad_ra;
982 registers_[ra] = bad_ra;
983 InitializeCoverage();
984 for (
int i = 0;
i < kNumExceptions;
i++) {
988 last_debugger_input_ =
NULL;
992 Simulator::~Simulator() {
1006 : external_function_(external_function),
1010 Isolate* isolate = Isolate::Current();
1011 next_ = isolate->simulator_redirection();
1012 Simulator::current(isolate)->
1013 FlushICache(isolate->simulator_i_cache(),
1014 reinterpret_cast<void*
>(&swi_instruction_),
1015 Instruction::kInstrSize);
1016 isolate->set_simulator_redirection(
this);
1019 void* address_of_swi_instruction() {
1020 return reinterpret_cast<void*
>(&swi_instruction_);
1023 void* external_function() {
return external_function_; }
1026 static Redirection* Get(
void* external_function,
1028 Isolate* isolate = Isolate::Current();
1029 Redirection* current = isolate->simulator_redirection();
1030 for (; current !=
NULL; current = current->next_) {
1031 if (current->external_function_ == external_function)
return current;
1033 return new Redirection(external_function, type);
1036 static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
1037 char* addr_of_swi =
reinterpret_cast<char*
>(swi_instruction);
1038 char* addr_of_redirection =
1039 addr_of_swi -
OFFSET_OF(Redirection, swi_instruction_);
1040 return reinterpret_cast<Redirection*
>(addr_of_redirection);
1043 static void* ReverseRedirection(
int32_t reg) {
1044 Redirection* redirection = FromSwiInstruction(
1045 reinterpret_cast<Instruction*
>(
reinterpret_cast<void*
>(reg)));
1046 return redirection->external_function();
1050 void* external_function_;
1057 void* Simulator::RedirectExternalReference(
void* external_function,
1059 Redirection* redirection = Redirection::Get(external_function, type);
1060 return redirection->address_of_swi_instruction();
1065 Simulator* Simulator::current(Isolate* isolate) {
1067 isolate->FindOrAllocatePerThreadDataForThisThread();
1071 Simulator* sim = isolate_data->simulator();
1074 sim =
new Simulator(isolate);
1075 isolate_data->set_simulator(sim);
1083 void Simulator::set_register(
int reg,
int32_t value) {
1086 pc_modified_ =
true;
1090 registers_[reg] = (reg == 0) ? 0 : value;
1094 void Simulator::set_dw_register(
int reg,
const int* dbl) {
1096 registers_[reg] = dbl[0];
1097 registers_[reg + 1] = dbl[1];
1101 void Simulator::set_fpu_register(
int fpureg, int64_t value) {
1104 FPUregisters_[fpureg] = value;
1108 void Simulator::set_fpu_register_word(
int fpureg,
int32_t value) {
1112 int32_t *pword =
reinterpret_cast<int32_t*
>(&FPUregisters_[fpureg]);
1117 void Simulator::set_fpu_register_hi_word(
int fpureg,
int32_t value) {
1121 int32_t *phiword = (
reinterpret_cast<int32_t*
>(&FPUregisters_[fpureg])) + 1;
1126 void Simulator::set_fpu_register_float(
int fpureg,
float value) {
1128 *bit_cast<float*>(&FPUregisters_[fpureg]) = value;
1132 void Simulator::set_fpu_register_double(
int fpureg,
double value) {
1135 *bit_cast<double*>(&FPUregisters_[fpureg]) = value;
1138 int64_t i64 = bit_cast<int64_t>(value);
1139 set_fpu_register_word(fpureg, i64 & 0xffffffff);
1140 set_fpu_register_word(fpureg + 1, i64 >> 32);
1147 int32_t Simulator::get_register(
int reg)
const {
1152 return registers_[reg] + ((reg ==
pc) ? Instruction::kPCReadOffset : 0);
1156 double Simulator::get_double_from_register_pair(
int reg) {
1160 double dm_val = 0.0;
1163 char buffer[2 *
sizeof(registers_[0])];
1164 memcpy(buffer, ®isters_[reg], 2 *
sizeof(registers_[0]));
1165 memcpy(&dm_val, buffer, 2 *
sizeof(registers_[0]));
1170 int64_t Simulator::get_fpu_register(
int fpureg)
const {
1173 return FPUregisters_[fpureg];
1177 int32_t Simulator::get_fpu_register_word(
int fpureg)
const {
1179 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
1183 int32_t Simulator::get_fpu_register_signed_word(
int fpureg)
const {
1185 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
1189 int32_t Simulator::get_fpu_register_hi_word(
int fpureg)
const {
1191 return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff);
1195 float Simulator::get_fpu_register_float(
int fpureg)
const {
1197 return *bit_cast<float*>(
const_cast<int64_t*
>(&FPUregisters_[fpureg]));
1201 double Simulator::get_fpu_register_double(
int fpureg)
const {
1204 return *bit_cast<double*>(&FPUregisters_[fpureg]);
1208 i64 =
static_cast<uint32_t>(get_fpu_register_word(fpureg));
1209 i64 |=
static_cast<uint64_t
>(get_fpu_register_word(fpureg + 1)) << 32;
1210 return bit_cast<double>(i64);
1218 void Simulator::GetFpArgs(
double* x,
double*
y,
int32_t* z) {
1220 *x = get_fpu_register_double(12);
1221 *
y = get_fpu_register_double(14);
1222 *z = get_register(a2);
1227 char buffer[
sizeof(*x)];
1231 reg_buffer[0] = get_register(a0);
1232 reg_buffer[1] = get_register(a1);
1233 memcpy(x, buffer,
sizeof(buffer));
1235 reg_buffer[0] = get_register(a2);
1236 reg_buffer[1] = get_register(a3);
1237 memcpy(
y, buffer,
sizeof(buffer));
1239 reg_buffer[0] = get_register(a2);
1240 memcpy(z, buffer,
sizeof(*z));
1246 void Simulator::SetFpResult(
const double& result) {
1248 set_fpu_register_double(0, result);
1250 char buffer[2 *
sizeof(registers_[0])];
1252 memcpy(buffer, &result,
sizeof(buffer));
1254 set_register(v0, reg_buffer[0]);
1255 set_register(v1, reg_buffer[1]);
1261 void Simulator::set_fcsr_bit(
uint32_t cc,
bool value) {
1265 FCSR_ &= ~(1 <<
cc);
1271 return FCSR_ & (1 <<
cc);
1277 bool Simulator::set_fcsr_round_error(
double original,
double rounded) {
1279 double max_int32 = std::numeric_limits<int32_t>::max();
1282 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1287 if (original != rounded) {
1291 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
1296 if (rounded > max_int32 || rounded < min_int32) {
1308 void Simulator::set_pc(
int32_t value) {
1309 pc_modified_ =
true;
1310 registers_[
pc] = value;
1314 bool Simulator::has_bad_pc()
const {
1315 return ((registers_[
pc] == bad_ra) || (registers_[
pc] == end_sim_pc));
1320 int32_t Simulator::get_pc()
const {
1321 return registers_[
pc];
1333 int Simulator::ReadW(
int32_t addr, Instruction* instr) {
1334 if (addr >=0 && addr < 0x400) {
1336 PrintF(
"Memory read from bad address: 0x%08x, pc=0x%08x\n",
1337 addr,
reinterpret_cast<intptr_t
>(instr));
1338 MipsDebugger dbg(
this);
1342 intptr_t* ptr =
reinterpret_cast<intptr_t*
>(addr);
1347 reinterpret_cast<intptr_t
>(instr));
1348 MipsDebugger dbg(
this);
1354 void Simulator::WriteW(
int32_t addr,
int value, Instruction* instr) {
1355 if (addr >= 0 && addr < 0x400) {
1357 PrintF(
"Memory write to bad address: 0x%08x, pc=0x%08x\n",
1358 addr,
reinterpret_cast<intptr_t
>(instr));
1359 MipsDebugger dbg(
this);
1363 intptr_t* ptr =
reinterpret_cast<intptr_t*
>(addr);
1369 reinterpret_cast<intptr_t
>(instr));
1370 MipsDebugger dbg(
this);
1375 double Simulator::ReadD(
int32_t addr, Instruction* instr) {
1377 double* ptr =
reinterpret_cast<double*
>(addr);
1382 reinterpret_cast<intptr_t
>(instr));
1388 void Simulator::WriteD(
int32_t addr,
double value, Instruction* instr) {
1390 double* ptr =
reinterpret_cast<double*
>(addr);
1396 reinterpret_cast<intptr_t
>(instr));
1402 if ((addr & 1) == 0) {
1406 PrintF(
"Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1408 reinterpret_cast<intptr_t
>(instr));
1415 if ((addr & 1) == 0) {
1419 PrintF(
"Unaligned signed halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1421 reinterpret_cast<intptr_t
>(instr));
1427 void Simulator::WriteH(
int32_t addr,
uint16_t value, Instruction* instr) {
1428 if ((addr & 1) == 0) {
1433 PrintF(
"Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1435 reinterpret_cast<intptr_t
>(instr));
1440 void Simulator::WriteH(
int32_t addr,
int16_t value, Instruction* instr) {
1441 if ((addr & 1) == 0) {
1448 reinterpret_cast<intptr_t
>(instr));
1454 uint8_t* ptr =
reinterpret_cast<uint8_t*
>(addr);
1460 int8_t* ptr =
reinterpret_cast<int8_t*
>(addr);
1465 void Simulator::WriteB(
int32_t addr, uint8_t value) {
1466 uint8_t* ptr =
reinterpret_cast<uint8_t*
>(addr);
1471 void Simulator::WriteB(
int32_t addr, int8_t value) {
1472 int8_t* ptr =
reinterpret_cast<int8_t*
>(addr);
1478 uintptr_t Simulator::StackLimit()
const {
1481 return reinterpret_cast<uintptr_t>(stack_) + 1024;
1486 void Simulator::Format(Instruction* instr,
const char* format) {
1487 PrintF(
"Simulator found unsupported instruction:\n 0x%08x: %s\n",
1488 reinterpret_cast<intptr_t
>(instr), format);
1499 typedef int64_t (*SimulatorRuntimeCall)(
int32_t arg0,
1507 typedef int64_t (*SimulatorRuntimeCompareCall)(
double darg0,
double darg1);
1508 typedef double (*SimulatorRuntimeFPFPCall)(
double darg0,
double darg1);
1509 typedef double (*SimulatorRuntimeFPCall)(
double darg0);
1510 typedef double (*SimulatorRuntimeFPIntCall)(
double darg0,
int32_t arg0);
1514 typedef void (*SimulatorRuntimeDirectApiCall)(
int32_t arg0);
1515 typedef void (*SimulatorRuntimeProfilingApiCall)(
int32_t arg0,
void* arg1);
1518 typedef void (*SimulatorRuntimeDirectGetterCall)(
int32_t arg0,
int32_t arg1);
1519 typedef void (*SimulatorRuntimeProfilingGetterCall)(
1524 void Simulator::SoftwareInterrupt(Instruction* instr) {
1528 int32_t func = instr->FunctionFieldRaw();
1533 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1534 int32_t arg0 = get_register(a0);
1535 int32_t arg1 = get_register(a1);
1536 int32_t arg2 = get_register(a2);
1537 int32_t arg3 = get_register(a3);
1541 int32_t arg4 = stack_pointer[4];
1542 int32_t arg5 = stack_pointer[5];
1545 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1546 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1547 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1548 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1555 switch (redirection->type()) {
1556 case ExternalReference::BUILTIN_FP_FP_CALL:
1557 case ExternalReference::BUILTIN_COMPARE_CALL:
1559 arg0 = get_fpu_register_word(
f12);
1560 arg1 = get_fpu_register_hi_word(
f12);
1561 arg2 = get_fpu_register_word(
f14);
1562 arg3 = get_fpu_register_hi_word(
f14);
1564 arg0 = get_fpu_register_word(
f12);
1565 arg1 = get_fpu_register_word(
f13);
1566 arg2 = get_fpu_register_word(
f14);
1567 arg3 = get_fpu_register_word(
f15);
1570 case ExternalReference::BUILTIN_FP_CALL:
1572 arg0 = get_fpu_register_word(
f12);
1573 arg1 = get_fpu_register_hi_word(
f12);
1575 arg0 = get_fpu_register_word(
f12);
1576 arg1 = get_fpu_register_word(
f13);
1579 case ExternalReference::BUILTIN_FP_INT_CALL:
1581 arg0 = get_fpu_register_word(
f12);
1582 arg1 = get_fpu_register_hi_word(
f12);
1584 arg0 = get_fpu_register_word(
f12);
1585 arg1 = get_fpu_register_word(
f13);
1587 arg2 = get_register(a2);
1596 int32_t saved_ra = get_register(ra);
1599 reinterpret_cast<intptr_t
>(redirection->external_function());
1606 double dval0, dval1;
1608 int64_t iresult = 0;
1610 GetFpArgs(&dval0, &dval1, &ival);
1611 SimulatorRuntimeCall generic_target =
1612 reinterpret_cast<SimulatorRuntimeCall
>(external);
1613 if (::v8::internal::FLAG_trace_sim) {
1614 switch (redirection->type()) {
1615 case ExternalReference::BUILTIN_FP_FP_CALL:
1616 case ExternalReference::BUILTIN_COMPARE_CALL:
1617 PrintF(
"Call to host function at %p with args %f, %f",
1620 case ExternalReference::BUILTIN_FP_CALL:
1621 PrintF(
"Call to host function at %p with arg %f",
1624 case ExternalReference::BUILTIN_FP_INT_CALL:
1625 PrintF(
"Call to host function at %p with args %f, %d",
1633 switch (redirection->type()) {
1634 case ExternalReference::BUILTIN_COMPARE_CALL: {
1635 SimulatorRuntimeCompareCall target =
1636 reinterpret_cast<SimulatorRuntimeCompareCall
>(external);
1637 iresult = target(dval0, dval1);
1638 set_register(v0,
static_cast<int32_t>(iresult));
1639 set_register(v1,
static_cast<int32_t>(iresult >> 32));
1642 case ExternalReference::BUILTIN_FP_FP_CALL: {
1643 SimulatorRuntimeFPFPCall target =
1644 reinterpret_cast<SimulatorRuntimeFPFPCall
>(external);
1645 dresult = target(dval0, dval1);
1646 SetFpResult(dresult);
1649 case ExternalReference::BUILTIN_FP_CALL: {
1650 SimulatorRuntimeFPCall target =
1651 reinterpret_cast<SimulatorRuntimeFPCall
>(external);
1652 dresult = target(dval0);
1653 SetFpResult(dresult);
1656 case ExternalReference::BUILTIN_FP_INT_CALL: {
1657 SimulatorRuntimeFPIntCall target =
1658 reinterpret_cast<SimulatorRuntimeFPIntCall
>(external);
1659 dresult = target(dval0, ival);
1660 SetFpResult(dresult);
1667 if (::v8::internal::FLAG_trace_sim) {
1668 switch (redirection->type()) {
1669 case ExternalReference::BUILTIN_COMPARE_CALL:
1672 case ExternalReference::BUILTIN_FP_FP_CALL:
1673 case ExternalReference::BUILTIN_FP_CALL:
1674 case ExternalReference::BUILTIN_FP_INT_CALL:
1675 PrintF(
"Returned %f\n", dresult);
1682 }
else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1683 if (::v8::internal::FLAG_trace_sim) {
1684 PrintF(
"Call to host function at %p args %08x\n",
1685 reinterpret_cast<void*
>(external), arg0);
1687 SimulatorRuntimeDirectApiCall target =
1688 reinterpret_cast<SimulatorRuntimeDirectApiCall
>(external);
1691 redirection->type() == ExternalReference::PROFILING_API_CALL) {
1692 if (::v8::internal::FLAG_trace_sim) {
1693 PrintF(
"Call to host function at %p args %08x %08x\n",
1694 reinterpret_cast<void*
>(external), arg0, arg1);
1696 SimulatorRuntimeProfilingApiCall target =
1697 reinterpret_cast<SimulatorRuntimeProfilingApiCall
>(external);
1698 target(arg0, Redirection::ReverseRedirection(arg1));
1700 redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
1701 if (::v8::internal::FLAG_trace_sim) {
1702 PrintF(
"Call to host function at %p args %08x %08x\n",
1703 reinterpret_cast<void*
>(external), arg0, arg1);
1705 SimulatorRuntimeDirectGetterCall target =
1706 reinterpret_cast<SimulatorRuntimeDirectGetterCall
>(external);
1709 redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
1710 if (::v8::internal::FLAG_trace_sim) {
1711 PrintF(
"Call to host function at %p args %08x %08x %08x\n",
1712 reinterpret_cast<void*
>(external), arg0, arg1, arg2);
1714 SimulatorRuntimeProfilingGetterCall target =
1715 reinterpret_cast<SimulatorRuntimeProfilingGetterCall
>(external);
1716 target(arg0, arg1, Redirection::ReverseRedirection(arg2));
1718 SimulatorRuntimeCall target =
1719 reinterpret_cast<SimulatorRuntimeCall
>(external);
1720 if (::v8::internal::FLAG_trace_sim) {
1722 "Call to host function at %p "
1723 "args %08x, %08x, %08x, %08x, %08x, %08x\n",
1732 int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
1733 set_register(v0,
static_cast<int32_t>(result));
1734 set_register(v1,
static_cast<int32_t>(result >> 32));
1736 if (::v8::internal::FLAG_trace_sim) {
1737 PrintF(
"Returned %08x : %08x\n", get_register(v1), get_register(v0));
1739 set_register(ra, saved_ra);
1740 set_pc(get_register(ra));
1743 if (IsWatchpoint(code)) {
1744 PrintWatchpoint(code);
1746 IncreaseStopCounter(code);
1747 HandleStop(code, instr);
1751 MipsDebugger dbg(
this);
1758 bool Simulator::IsWatchpoint(
uint32_t code) {
1763 void Simulator::PrintWatchpoint(
uint32_t code) {
1764 MipsDebugger dbg(
this);
1766 PrintF(
"\n---- break %d marker: %3d (instr count: %8d) ----------"
1767 "----------------------------------",
1768 code, break_count_, icount_);
1773 void Simulator::HandleStop(
uint32_t code, Instruction* instr) {
1776 if (IsEnabledStop(code)) {
1777 MipsDebugger dbg(
this);
1780 set_pc(get_pc() + 2 * Instruction::kInstrSize);
1785 bool Simulator::IsStopInstruction(Instruction* instr) {
1786 int32_t func = instr->FunctionFieldRaw();
1792 bool Simulator::IsEnabledStop(
uint32_t code) {
1795 return !(watched_stops_[code].count & kStopDisabledBit);
1799 void Simulator::EnableStop(
uint32_t code) {
1800 if (!IsEnabledStop(code)) {
1801 watched_stops_[code].count &= ~kStopDisabledBit;
1806 void Simulator::DisableStop(
uint32_t code) {
1807 if (IsEnabledStop(code)) {
1808 watched_stops_[code].count |= kStopDisabledBit;
1813 void Simulator::IncreaseStopCounter(
uint32_t code) {
1815 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
1816 PrintF(
"Stop counter for code %i has overflowed.\n"
1817 "Enabling this code and reseting the counter to 0.\n", code);
1818 watched_stops_[code].count = 0;
1821 watched_stops_[code].count++;
1827 void Simulator::PrintStopInfo(
uint32_t code) {
1829 PrintF(
"That is a watchpoint, not a stop.\n");
1835 const char* state = IsEnabledStop(code) ?
"Enabled" :
"Disabled";
1836 int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
1839 if (watched_stops_[code].desc) {
1840 PrintF(
"stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
1841 code, code, state, count, watched_stops_[code].desc);
1843 PrintF(
"stop %i - 0x%x: \t%s, \tcounter = %i\n",
1844 code, code, state, count);
1850 void Simulator::SignalExceptions() {
1851 for (
int i = 1;
i < kNumExceptions;
i++) {
1852 if (exceptions[
i] != 0) {
1853 V8_Fatal(__FILE__, __LINE__,
"Error: Exception %i raised.",
i);
1861 void Simulator::ConfigureTypeRegister(Instruction* instr,
1867 bool* do_interrupt) {
1873 const Opcode op = instr->OpcodeFieldRaw();
1874 const int32_t rs_reg = instr->RsValue();
1875 const int32_t rs = get_register(rs_reg);
1877 const int32_t rt_reg = instr->RtValue();
1878 const int32_t rt = get_register(rt_reg);
1880 const int32_t rd_reg = instr->RdValue();
1881 const uint32_t sa = instr->SaValue();
1883 const int32_t fs_reg = instr->FsValue();
1889 switch (instr->RsFieldRaw()) {
1896 *alu_out = get_fpu_register_word(fs_reg);
1899 *alu_out = get_fpu_register_hi_word(fs_reg);
1919 switch (instr->FunctionFieldRaw()) {
1922 *next_pc = get_register(instr->RsValue());
1923 *return_addr_reg = instr->RdValue();
1926 *alu_out = rt << sa;
1932 *alu_out = rt_u >> sa;
1937 *alu_out = (rt_u >> sa) | (rt_u << (32 - sa));
1941 *alu_out = rt >> sa;
1944 *alu_out = rt << rs;
1950 *alu_out = rt_u >> rs;
1955 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u));
1959 *alu_out = rt >> rs;
1963 DCHECK(instr->SaValue() == 0);
1964 *alu_out = get_register(HI);
1968 DCHECK(instr->SaValue() == 1);
1973 *alu_out = get_register(LO);
1977 *i64hilo =
static_cast<int64_t
>(rs) *
static_cast<int64_t
>(rt);
1979 switch (instr->SaValue()) {
1982 *i64hilo =
static_cast<int64_t
>(rs) *
static_cast<int64_t
>(rt);
1992 *u64hilo =
static_cast<uint64_t
>(rs_u) *
1993 static_cast<uint64_t
>(rt_u);
1995 switch (instr->SaValue()) {
1998 *u64hilo =
static_cast<uint64_t
>(rs_u) *
1999 static_cast<uint64_t
>(rt_u);
2008 if (HaveSameSign(rs, rt)) {
2010 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
2011 }
else if (rs < 0) {
2012 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
2021 if (!HaveSameSign(rs, rt)) {
2023 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt);
2024 }
else if (rs < 0) {
2025 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt);
2043 *alu_out = ~(rs | rt);
2046 *alu_out = rs < rt ? 1 : 0;
2049 *alu_out = rs_u < rt_u ? 1 : 0;
2053 *do_interrupt =
true;
2056 *do_interrupt = rs >= rt;
2059 *do_interrupt = rs_u >= rt_u;
2062 *do_interrupt = rs < rt;
2065 *do_interrupt = rs_u < rt_u;
2068 *do_interrupt = rs == rt;
2071 *do_interrupt = rs != rt;
2087 switch (instr->FunctionFieldRaw()) {
2089 *alu_out = rs_u * rt_u;
2101 switch (instr->FunctionFieldRaw()) {
2109 *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
2119 *alu_out = (rs_u & (mask << lsb)) >> lsb;
2132 void Simulator::DecodeTypeRegister(Instruction* instr) {
2134 const Opcode op = instr->OpcodeFieldRaw();
2135 const int32_t rs_reg = instr->RsValue();
2136 const int32_t rs = get_register(rs_reg);
2138 const int32_t rt_reg = instr->RtValue();
2139 const int32_t rt = get_register(rt_reg);
2141 const int32_t rd_reg = instr->RdValue();
2143 const int32_t fr_reg = instr->FrValue();
2144 const int32_t fs_reg = instr->FsValue();
2145 const int32_t ft_reg = instr->FtValue();
2146 const int32_t fd_reg = instr->FdValue();
2147 int64_t i64hilo = 0;
2148 uint64_t u64hilo = 0;
2156 bool do_interrupt =
false;
2160 int32_t current_pc = get_pc();
2166 ConfigureTypeRegister(instr,
2180 switch (instr->RsFieldRaw()) {
2182 set_register(rt_reg, alu_out);
2185 set_register(rt_reg, alu_out);
2188 set_register(rt_reg, alu_out);
2193 FCSR_ = registers_[rt_reg];
2197 set_fpu_register_hi_word(fs_reg, 0);
2198 set_fpu_register_word(fs_reg, registers_[rt_reg]);
2201 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]);
2205 switch (instr->FunctionFieldRaw()) {
2207 f = get_fpu_register_float(fs_reg);
2208 set_fpu_register_double(fd_reg,
static_cast<double>(f));
2220 fs = get_fpu_register_double(fs_reg);
2221 ft = get_fpu_register_double(ft_reg);
2222 cc = instr->FCccValue();
2223 fcsr_cc = get_fcsr_condition_bit(
cc);
2224 switch (instr->FunctionFieldRaw()) {
2226 set_fpu_register_double(fd_reg, fs + ft);
2229 set_fpu_register_double(fd_reg, fs - ft);
2232 set_fpu_register_double(fd_reg, fs * ft);
2235 set_fpu_register_double(fd_reg, fs / ft);
2238 set_fpu_register_double(fd_reg, fabs(fs));
2241 set_fpu_register_double(fd_reg, fs);
2244 set_fpu_register_double(fd_reg, -fs);
2247 set_fpu_register_double(fd_reg, sqrt(fs));
2250 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2253 set_fcsr_bit(fcsr_cc, (fs == ft));
2256 set_fcsr_bit(fcsr_cc,
2257 (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2260 set_fcsr_bit(fcsr_cc, (fs < ft));
2263 set_fcsr_bit(fcsr_cc,
2264 (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
2267 set_fcsr_bit(fcsr_cc, (fs <= ft));
2270 set_fcsr_bit(fcsr_cc,
2271 (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2275 DCHECK((FCSR_ & 3) == 0);
2279 double rounded = std::floor(fs + 0.5);
2281 if ((result & 1) != 0 && result - fs == 0.5) {
2286 set_fpu_register_word(fd_reg, result);
2287 if (set_fcsr_round_error(fs, rounded)) {
2294 double rounded = trunc(fs);
2296 set_fpu_register_word(fd_reg, result);
2297 if (set_fcsr_round_error(fs, rounded)) {
2304 double rounded = std::floor(fs);
2306 set_fpu_register_word(fd_reg, result);
2307 if (set_fcsr_round_error(fs, rounded)) {
2314 double rounded = std::ceil(fs);
2316 set_fpu_register_word(fd_reg, result);
2317 if (set_fcsr_round_error(fs, rounded)) {
2323 set_fpu_register_float(fd_reg,
static_cast<float>(fs));
2326 double rounded = trunc(fs);
2327 i64 =
static_cast<int64_t
>(rounded);
2329 set_fpu_register(fd_reg, i64);
2331 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2332 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2337 double rounded = trunc(fs);
2338 i64 =
static_cast<int64_t
>(rounded);
2340 set_fpu_register(fd_reg, i64);
2342 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2343 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2349 fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5);
2350 i64 =
static_cast<int64_t
>(rounded);
2352 set_fpu_register(fd_reg, i64);
2354 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2355 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2360 i64 =
static_cast<int64_t
>(std::floor(fs));
2362 set_fpu_register(fd_reg, i64);
2364 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2365 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2369 i64 =
static_cast<int64_t
>(std::ceil(fs));
2371 set_fpu_register(fd_reg, i64);
2373 set_fpu_register_word(fd_reg, i64 & 0xffffffff);
2374 set_fpu_register_word(fd_reg + 1, i64 >> 32);
2385 switch (instr->FunctionFieldRaw()) {
2387 alu_out = get_fpu_register_signed_word(fs_reg);
2388 set_fpu_register_float(fd_reg,
static_cast<float>(alu_out));
2391 alu_out = get_fpu_register_signed_word(fs_reg);
2392 set_fpu_register_double(fd_reg,
static_cast<double>(alu_out));
2399 fs = get_fpu_register_double(fs_reg);
2400 ft = get_fpu_register_double(ft_reg);
2401 switch (instr->FunctionFieldRaw()) {
2406 i64 = get_fpu_register(fs_reg);
2408 i64 =
static_cast<uint32_t>(get_fpu_register_word(fs_reg));
2409 i64 |=
static_cast<int64_t
>(
2410 get_fpu_register_word(fs_reg + 1)) << 32;
2412 set_fpu_register_double(fd_reg,
static_cast<double>(i64));
2421 if (std::isnan(fs) || std::isnan(ft)) {
2422 set_fpu_register(fd_reg, -1);
2424 set_fpu_register(fd_reg, 0);
2429 set_fpu_register(fd_reg, -1);
2431 set_fpu_register(fd_reg, 0);
2435 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
2436 set_fpu_register(fd_reg, -1);
2438 set_fpu_register(fd_reg, 0);
2443 set_fpu_register(fd_reg, -1);
2445 set_fpu_register(fd_reg, 0);
2449 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
2450 set_fpu_register(fd_reg, -1);
2452 set_fpu_register(fd_reg, 0);
2457 set_fpu_register(fd_reg, -1);
2459 set_fpu_register(fd_reg, 0);
2463 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
2464 set_fpu_register(fd_reg, -1);
2466 set_fpu_register(fd_reg, 0);
2478 switch (instr->FunctionFieldRaw()) {
2481 fr = get_fpu_register_double(fr_reg);
2482 fs = get_fpu_register_double(fs_reg);
2483 ft = get_fpu_register_double(ft_reg);
2484 set_fpu_register_double(fd_reg, fs * ft + fr);
2491 switch (instr->FunctionFieldRaw()) {
2493 Instruction* branch_delay_instr =
reinterpret_cast<Instruction*
>(
2494 current_pc+Instruction::kInstrSize);
2495 BranchDelayInstructionDecode(branch_delay_instr);
2497 pc_modified_ =
true;
2501 Instruction* branch_delay_instr =
reinterpret_cast<Instruction*
>(
2502 current_pc+Instruction::kInstrSize);
2503 BranchDelayInstructionDecode(branch_delay_instr);
2504 set_register(return_addr_reg,
2505 current_pc + 2 * Instruction::kInstrSize);
2507 pc_modified_ =
true;
2513 set_register(LO,
static_cast<int32_t>(i64hilo & 0xffffffff));
2514 set_register(HI,
static_cast<int32_t>(i64hilo >> 32));
2516 switch (instr->SaValue()) {
2518 set_register(rd_reg,
2519 static_cast<int32_t>(i64hilo & 0xffffffff));
2522 set_register(rd_reg,
static_cast<int32_t>(i64hilo >> 32));
2532 set_register(LO,
static_cast<int32_t>(u64hilo & 0xffffffff));
2533 set_register(HI,
static_cast<int32_t>(u64hilo >> 32));
2535 switch (instr->SaValue()) {
2537 set_register(rd_reg,
2538 static_cast<int32_t>(u64hilo & 0xffffffff));
2541 set_register(rd_reg,
static_cast<int32_t>(u64hilo >> 32));
2551 switch (instr->SaValue()) {
2553 if (rs == INT_MIN && rt == -1) {
2554 set_register(rd_reg, INT_MIN);
2555 }
else if (rt != 0) {
2556 set_register(rd_reg, rs / rt);
2560 if (rs == INT_MIN && rt == -1) {
2561 set_register(rd_reg, 0);
2562 }
else if (rt != 0) {
2563 set_register(rd_reg, rs % rt);
2575 if (rs == INT_MIN && rt == -1) {
2576 set_register(LO, INT_MIN);
2577 set_register(HI, 0);
2578 }
else if (rt != 0) {
2579 set_register(LO, rs / rt);
2580 set_register(HI, rs % rt);
2586 switch (instr->SaValue()) {
2589 set_register(rd_reg, rs_u / rt_u);
2594 set_register(rd_reg, rs_u % rt_u);
2603 set_register(LO, rs_u / rt_u);
2604 set_register(HI, rs_u % rt_u);
2617 SoftwareInterrupt(instr);
2622 if (rt) set_register(rd_reg, rs);
2626 uint32_t fcsr_cc = get_fcsr_condition_bit(
cc);
2627 if (instr->Bit(16)) {
2628 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
2630 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
2635 if (!rt) set_register(rd_reg, rs);
2638 set_register(rd_reg, alu_out);
2642 switch (instr->FunctionFieldRaw()) {
2644 set_register(rd_reg, alu_out);
2646 set_register(LO, Unpredictable);
2647 set_register(HI, Unpredictable);
2650 set_register(rd_reg, alu_out);
2654 switch (instr->FunctionFieldRaw()) {
2657 set_register(rt_reg, alu_out);
2661 set_register(rt_reg, alu_out);
2671 set_register(rd_reg, alu_out);
2677 void Simulator::DecodeTypeImmediate(Instruction* instr) {
2679 Opcode op = instr->OpcodeFieldRaw();
2680 int32_t rs = get_register(instr->RsValue());
2682 int32_t rt_reg = instr->RtValue();
2683 int32_t rt = get_register(rt_reg);
2684 int16_t imm16 = instr->Imm16Value();
2686 int32_t ft_reg = instr->FtValue();
2690 uint32_t oe_imm16 = 0xffff & imm16;
2695 int32_t current_pc = get_pc();
2700 bool do_branch =
false;
2701 bool execute_branch_delay_instruction =
false;
2706 double fp_out = 0.0;
2718 switch (instr->RsFieldRaw()) {
2720 cc = instr->FBccValue();
2721 fcsr_cc = get_fcsr_condition_bit(
cc);
2722 cc_value = test_fcsr_bit(fcsr_cc);
2723 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
2724 execute_branch_delay_instruction =
true;
2727 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2733 ft = get_fpu_register(ft_reg);
2734 do_branch = (ft & 0x1) ?
false :
true;
2735 execute_branch_delay_instruction =
true;
2738 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2744 ft = get_fpu_register(ft_reg);
2745 do_branch = (ft & 0x1) ?
true :
false;
2746 execute_branch_delay_instruction =
true;
2749 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2760 switch (instr->RtFieldRaw()) {
2762 do_branch = (rs < 0);
2768 do_branch = rs >= 0;
2771 do_branch = rs >= 0;
2776 switch (instr->RtFieldRaw()) {
2782 execute_branch_delay_instruction =
true;
2785 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2786 if (instr->IsLinkingInstruction()) {
2800 do_branch = (rs == rt);
2803 do_branch = rs != rt;
2806 do_branch = rs <= 0;
2813 if (HaveSameSign(rs, se_imm16)) {
2815 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
2816 }
else if (rs < 0) {
2817 exceptions[kIntegerUnderflow] =
2818 rs < (Registers::kMinValue - se_imm16);
2821 alu_out = rs + se_imm16;
2824 alu_out = rs + se_imm16;
2827 alu_out = (rs < se_imm16) ? 1 : 0;
2830 alu_out = (rs_u < static_cast<uint32_t>(se_imm16)) ? 1 : 0;
2833 alu_out = rs & oe_imm16;
2836 alu_out = rs | oe_imm16;
2839 alu_out = rs ^ oe_imm16;
2842 alu_out = (oe_imm16 << 16);
2846 addr = rs + se_imm16;
2847 alu_out = ReadB(addr);
2850 addr = rs + se_imm16;
2851 alu_out = ReadH(addr, instr);
2857 uint32_t mask = (1 << byte_shift * 8) - 1;
2858 addr = rs + se_imm16 - al_offset;
2859 alu_out = ReadW(addr, instr);
2860 alu_out <<= byte_shift * 8;
2861 alu_out |= rt & mask;
2865 addr = rs + se_imm16;
2866 alu_out = ReadW(addr, instr);
2869 addr = rs + se_imm16;
2870 alu_out = ReadBU(addr);
2873 addr = rs + se_imm16;
2874 alu_out = ReadHU(addr, instr);
2880 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
2881 addr = rs + se_imm16 - al_offset;
2882 alu_out = ReadW(addr, instr);
2883 alu_out =
static_cast<uint32_t> (alu_out) >> al_offset * 8;
2884 alu_out |= rt & mask;
2888 addr = rs + se_imm16;
2891 addr = rs + se_imm16;
2896 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
2897 addr = rs + se_imm16 - al_offset;
2898 mem_value = ReadW(addr, instr) & mask;
2899 mem_value |=
static_cast<uint32_t>(rt) >> byte_shift * 8;
2903 addr = rs + se_imm16;
2907 uint32_t mask = (1 << al_offset * 8) - 1;
2908 addr = rs + se_imm16 - al_offset;
2909 mem_value = ReadW(addr, instr);
2910 mem_value = (rt << al_offset * 8) | (mem_value & mask);
2914 addr = rs + se_imm16;
2915 alu_out = ReadW(addr, instr);
2918 addr = rs + se_imm16;
2919 fp_out = ReadD(addr, instr);
2923 addr = rs + se_imm16;
2940 execute_branch_delay_instruction =
true;
2943 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
2944 if (instr->IsLinkingInstruction()) {
2945 set_register(31, current_pc + 2* Instruction::kInstrSize);
2948 next_pc = current_pc + 2 * Instruction::kInstrSize;
2960 set_register(rt_reg, alu_out);
2970 set_register(rt_reg, alu_out);
2973 WriteB(addr,
static_cast<int8_t
>(rt));
2976 WriteH(addr,
static_cast<uint16_t>(rt), instr);
2979 WriteW(addr, mem_value, instr);
2982 WriteW(addr, rt, instr);
2985 WriteW(addr, mem_value, instr);
2988 set_fpu_register_hi_word(ft_reg, 0);
2989 set_fpu_register_word(ft_reg, alu_out);
2992 set_fpu_register_double(ft_reg, fp_out);
2995 addr = rs + se_imm16;
2996 WriteW(addr, get_fpu_register_word(ft_reg), instr);
2999 addr = rs + se_imm16;
3000 WriteD(addr, get_fpu_register_double(ft_reg), instr);
3007 if (execute_branch_delay_instruction) {
3011 Instruction* branch_delay_instr =
3012 reinterpret_cast<Instruction*
>(current_pc+Instruction::kInstrSize);
3013 BranchDelayInstructionDecode(branch_delay_instr);
3017 if (next_pc != bad_ra) {
3024 void Simulator::DecodeTypeJump(Instruction* instr) {
3026 int32_t current_pc = get_pc();
3028 int32_t pc_high_bits = current_pc & 0xf0000000;
3030 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);
3035 Instruction* branch_delay_instr =
3036 reinterpret_cast<Instruction*
>(current_pc + Instruction::kInstrSize);
3037 BranchDelayInstructionDecode(branch_delay_instr);
3041 if (instr->IsLinkingInstruction()) {
3042 set_register(31, current_pc + 2 * Instruction::kInstrSize);
3045 pc_modified_ =
true;
3050 void Simulator::InstructionDecode(Instruction* instr) {
3051 if (v8::internal::FLAG_check_icache) {
3052 CheckICache(isolate_->simulator_i_cache(), instr);
3054 pc_modified_ =
false;
3055 if (::v8::internal::FLAG_trace_sim) {
3060 dasm.InstructionDecode(buffer,
reinterpret_cast<byte*
>(instr));
3061 PrintF(
" 0x%08x %s\n",
reinterpret_cast<intptr_t
>(instr),
3065 switch (instr->InstructionType()) {
3066 case Instruction::kRegisterType:
3067 DecodeTypeRegister(instr);
3069 case Instruction::kImmediateType:
3070 DecodeTypeImmediate(instr);
3072 case Instruction::kJumpType:
3073 DecodeTypeJump(instr);
3078 if (!pc_modified_) {
3079 set_register(
pc,
reinterpret_cast<int32_t>(instr) +
3080 Instruction::kInstrSize);
3086 void Simulator::Execute() {
3089 int program_counter = get_pc();
3090 if (::v8::internal::FLAG_stop_sim_at == 0) {
3093 while (program_counter != end_sim_pc) {
3094 Instruction* instr =
reinterpret_cast<Instruction*
>(program_counter);
3096 InstructionDecode(instr);
3097 program_counter = get_pc();
3102 while (program_counter != end_sim_pc) {
3103 Instruction* instr =
reinterpret_cast<Instruction*
>(program_counter);
3105 if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
3106 MipsDebugger dbg(
this);
3109 InstructionDecode(instr);
3111 program_counter = get_pc();
3117 void Simulator::CallInternal(
byte* entry) {
3119 set_register(
pc,
reinterpret_cast<int32_t>(entry));
3123 set_register(ra, end_sim_pc);
3136 int32_t gp_val = get_register(gp);
3142 int32_t callee_saved_value = icount_;
3143 set_register(
s0, callee_saved_value);
3144 set_register(
s1, callee_saved_value);
3145 set_register(
s2, callee_saved_value);
3146 set_register(
s3, callee_saved_value);
3147 set_register(
s4, callee_saved_value);
3148 set_register(
s5, callee_saved_value);
3149 set_register(
s6, callee_saved_value);
3150 set_register(
s7, callee_saved_value);
3151 set_register(gp, callee_saved_value);
3152 set_register(
fp, callee_saved_value);
3158 CHECK_EQ(callee_saved_value, get_register(
s0));
3159 CHECK_EQ(callee_saved_value, get_register(
s1));
3160 CHECK_EQ(callee_saved_value, get_register(
s2));
3161 CHECK_EQ(callee_saved_value, get_register(
s3));
3162 CHECK_EQ(callee_saved_value, get_register(
s4));
3163 CHECK_EQ(callee_saved_value, get_register(
s5));
3164 CHECK_EQ(callee_saved_value, get_register(
s6));
3165 CHECK_EQ(callee_saved_value, get_register(
s7));
3166 CHECK_EQ(callee_saved_value, get_register(gp));
3167 CHECK_EQ(callee_saved_value, get_register(
fp));
3170 set_register(
s0, s0_val);
3171 set_register(
s1, s1_val);
3172 set_register(
s2, s2_val);
3173 set_register(
s3, s3_val);
3174 set_register(
s4, s4_val);
3175 set_register(
s5, s5_val);
3176 set_register(
s6, s6_val);
3177 set_register(
s7, s7_val);
3178 set_register(gp, gp_val);
3179 set_register(
sp, sp_val);
3180 set_register(
fp, fp_val);
3184 int32_t Simulator::Call(
byte* entry,
int argument_count, ...) {
3186 va_start(parameters, argument_count);
3190 DCHECK(argument_count >= 4);
3191 set_register(a0, va_arg(parameters,
int32_t));
3192 set_register(a1, va_arg(parameters,
int32_t));
3193 set_register(a2, va_arg(parameters,
int32_t));
3194 set_register(a3, va_arg(parameters,
int32_t));
3197 int original_stack = get_register(
sp);
3199 int entry_stack = (original_stack - (argument_count - 4) *
sizeof(
int32_t)
3201 if (base::OS::ActivationFrameAlignment() != 0) {
3202 entry_stack &= -base::OS::ActivationFrameAlignment();
3205 intptr_t* stack_argument =
reinterpret_cast<intptr_t*
>(entry_stack);
3206 for (
int i = 4;
i < argument_count;
i++) {
3210 set_register(
sp, entry_stack);
3212 CallInternal(entry);
3216 set_register(
sp, original_stack);
3218 int32_t result = get_register(v0);
3223 double Simulator::CallFP(
byte* entry,
double d0,
double d1) {
3225 set_fpu_register_double(
f12,
d0);
3226 set_fpu_register_double(
f14,
d1);
3229 DCHECK(
sizeof(buffer[0]) * 2 ==
sizeof(
d0));
3230 memcpy(buffer, &
d0,
sizeof(
d0));
3231 set_dw_register(a0, buffer);
3232 memcpy(buffer, &
d1,
sizeof(
d1));
3233 set_dw_register(a2, buffer);
3235 CallInternal(entry);
3237 return get_fpu_register_double(
f0);
3239 return get_double_from_register_pair(v0);
3245 int new_sp = get_register(
sp) -
sizeof(
uintptr_t);
3247 *stack_slot = address;
3248 set_register(
sp, new_sp);
3254 int current_sp = get_register(
sp);
static int Number(const char *name)
static const char * Name(int reg)
static int Number(const char *name)
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
static const FpuMode kFpuMode
const bool IsMipsSoftFloatABI
#define UNIMPLEMENTED_MIPS()
#define IsMipsArchVariant(check)
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
void V8_Fatal(const char *file, int line, const char *format,...)
#define CHECK_EQ(expected, value)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define OFFSET_OF(type, field)
uint32_t CountLeadingZeros32(uint32_t value)
LinkageHelper< ArmLinkageHelperTraits > LH
void DeleteArray(T *array)
char * ReadLine(const char *prompt)
TypeImpl< ZoneTypeConfig > Type
static int min(int a, int b)
const intptr_t kPointerAlignmentMask
const LowDwVfpRegister d1
const Instr rtCallRedirInstr
const uint32_t kMaxStopCode
const uint32_t kMaxWatchpointCode
const LowDwVfpRegister d0
kSerializedDataOffset Object
const int kNumFPURegisters
const int kInvalidFPURegister
const int kNumSimuRegisters
const int kInvalidRegister
TemplateHashMapImpl< FreeStoreAllocationPolicy > HashMap
void PrintF(const char *format,...)
const int kCArgsSlotsSize
const int kBranchReturnOffset
const uint32_t kFCSRInvalidOpFlagBit
const uint32_t kFPUInvalidResult
const uint32_t kFCSROverflowFlagBit
const unsigned kInstructionSize
const uint32_t kFCSRUnderflowFlagBit
const intptr_t kDoubleAlignmentMask
const uint32_t kFCSRInexactFlagBit
Debugger support for the V8 JavaScript engine.