1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <limits.h> 6 #include <stdarg.h> 7 #include <stdlib.h> 8 #include <cmath> 9 10 #include "src/v8.h" 11 12 #if V8_TARGET_ARCH_MIPS 13 14 #include "src/cpu.h" 15 #include "src/disasm.h" 16 #include "src/assembler.h" 17 #include "src/globals.h" // Need the BitCast. 18 #include "src/mips/constants-mips.h" 19 #include "src/mips/simulator-mips.h" 20 21 22 // Only build the simulator if not compiling for real MIPS hardware. 23 #if defined(USE_SIMULATOR) 24 25 namespace v8 { 26 namespace internal { 27 28 // Utils functions. 29 bool HaveSameSign(int32_t a, int32_t b) { 30 return ((a ^ b) >= 0); 31 } 32 33 34 uint32_t get_fcsr_condition_bit(uint32_t cc) { 35 if (cc == 0) { 36 return 23; 37 } else { 38 return 24 + cc; 39 } 40 } 41 42 43 // This macro provides a platform independent use of sscanf. The reason for 44 // SScanF not being implemented in a platform independent was through 45 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time 46 // Library does not provide vsscanf. 47 #define SScanF sscanf // NOLINT 48 49 // The MipsDebugger class is used by the simulator while debugging simulated 50 // code. 51 class MipsDebugger { 52 public: 53 explicit MipsDebugger(Simulator* sim) : sim_(sim) { } 54 ~MipsDebugger(); 55 56 void Stop(Instruction* instr); 57 void Debug(); 58 // Print all registers with a nice formatting. 59 void PrintAllRegs(); 60 void PrintAllRegsIncludingFPU(); 61 62 private: 63 // We set the breakpoint code to 0xfffff to easily recognize it. 64 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6; 65 static const Instr kNopInstr = 0x0; 66 67 Simulator* sim_; 68 69 int32_t GetRegisterValue(int regnum); 70 int32_t GetFPURegisterValueInt(int regnum); 71 int64_t GetFPURegisterValueLong(int regnum); 72 float GetFPURegisterValueFloat(int regnum); 73 double GetFPURegisterValueDouble(int regnum); 74 bool GetValue(const char* desc, int32_t* value); 75 76 // Set or delete a breakpoint. Returns true if successful. 77 bool SetBreakpoint(Instruction* breakpc); 78 bool DeleteBreakpoint(Instruction* breakpc); 79 80 // Undo and redo all breakpoints. This is needed to bracket disassembly and 81 // execution to skip past breakpoints when run from the debugger. 82 void UndoBreakpoints(); 83 void RedoBreakpoints(); 84 }; 85 86 87 MipsDebugger::~MipsDebugger() { 88 } 89 90 91 #ifdef GENERATED_CODE_COVERAGE 92 static FILE* coverage_log = NULL; 93 94 95 static void InitializeCoverage() { 96 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 97 if (file_name != NULL) { 98 coverage_log = fopen(file_name, "aw+"); 99 } 100 } 101 102 103 void MipsDebugger::Stop(Instruction* instr) { 104 // Get the stop code. 105 uint32_t code = instr->Bits(25, 6); 106 // Retrieve the encoded address, which comes just after this stop. 107 char** msg_address = 108 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); 109 char* msg = *msg_address; 110 ASSERT(msg != NULL); 111 112 // Update this stop description. 113 if (!watched_stops_[code].desc) { 114 watched_stops_[code].desc = msg; 115 } 116 117 if (strlen(msg) > 0) { 118 if (coverage_log != NULL) { 119 fprintf(coverage_log, "%s\n", str); 120 fflush(coverage_log); 121 } 122 // Overwrite the instruction and address with nops. 123 instr->SetInstructionBits(kNopInstr); 124 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); 125 } 126 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize); 127 } 128 129 130 #else // GENERATED_CODE_COVERAGE 131 132 #define UNSUPPORTED() printf("Unsupported instruction.\n"); 133 134 static void InitializeCoverage() {} 135 136 137 void MipsDebugger::Stop(Instruction* instr) { 138 // Get the stop code. 139 uint32_t code = instr->Bits(25, 6); 140 // Retrieve the encoded address, which comes just after this stop. 141 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + 142 Instruction::kInstrSize); 143 // Update this stop description. 144 if (!sim_->watched_stops_[code].desc) { 145 sim_->watched_stops_[code].desc = msg; 146 } 147 PrintF("Simulator hit %s (%u)\n", msg, code); 148 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize); 149 Debug(); 150 } 151 #endif // GENERATED_CODE_COVERAGE 152 153 154 int32_t MipsDebugger::GetRegisterValue(int regnum) { 155 if (regnum == kNumSimuRegisters) { 156 return sim_->get_pc(); 157 } else { 158 return sim_->get_register(regnum); 159 } 160 } 161 162 163 int32_t MipsDebugger::GetFPURegisterValueInt(int regnum) { 164 if (regnum == kNumFPURegisters) { 165 return sim_->get_pc(); 166 } else { 167 return sim_->get_fpu_register(regnum); 168 } 169 } 170 171 172 int64_t MipsDebugger::GetFPURegisterValueLong(int regnum) { 173 if (regnum == kNumFPURegisters) { 174 return sim_->get_pc(); 175 } else { 176 return sim_->get_fpu_register_long(regnum); 177 } 178 } 179 180 181 float MipsDebugger::GetFPURegisterValueFloat(int regnum) { 182 if (regnum == kNumFPURegisters) { 183 return sim_->get_pc(); 184 } else { 185 return sim_->get_fpu_register_float(regnum); 186 } 187 } 188 189 190 double MipsDebugger::GetFPURegisterValueDouble(int regnum) { 191 if (regnum == kNumFPURegisters) { 192 return sim_->get_pc(); 193 } else { 194 return sim_->get_fpu_register_double(regnum); 195 } 196 } 197 198 199 bool MipsDebugger::GetValue(const char* desc, int32_t* value) { 200 int regnum = Registers::Number(desc); 201 int fpuregnum = FPURegisters::Number(desc); 202 203 if (regnum != kInvalidRegister) { 204 *value = GetRegisterValue(regnum); 205 return true; 206 } else if (fpuregnum != kInvalidFPURegister) { 207 *value = GetFPURegisterValueInt(fpuregnum); 208 return true; 209 } else if (strncmp(desc, "0x", 2) == 0) { 210 return SScanF(desc, "%x", reinterpret_cast<uint32_t*>(value)) == 1; 211 } else { 212 return SScanF(desc, "%i", value) == 1; 213 } 214 return false; 215 } 216 217 218 bool MipsDebugger::SetBreakpoint(Instruction* breakpc) { 219 // Check if a breakpoint can be set. If not return without any side-effects. 220 if (sim_->break_pc_ != NULL) { 221 return false; 222 } 223 224 // Set the breakpoint. 225 sim_->break_pc_ = breakpc; 226 sim_->break_instr_ = breakpc->InstructionBits(); 227 // Not setting the breakpoint instruction in the code itself. It will be set 228 // when the debugger shell continues. 229 return true; 230 } 231 232 233 bool MipsDebugger::DeleteBreakpoint(Instruction* breakpc) { 234 if (sim_->break_pc_ != NULL) { 235 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 236 } 237 238 sim_->break_pc_ = NULL; 239 sim_->break_instr_ = 0; 240 return true; 241 } 242 243 244 void MipsDebugger::UndoBreakpoints() { 245 if (sim_->break_pc_ != NULL) { 246 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 247 } 248 } 249 250 251 void MipsDebugger::RedoBreakpoints() { 252 if (sim_->break_pc_ != NULL) { 253 sim_->break_pc_->SetInstructionBits(kBreakpointInstr); 254 } 255 } 256 257 258 void MipsDebugger::PrintAllRegs() { 259 #define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n) 260 261 PrintF("\n"); 262 // at, v0, a0. 263 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 264 REG_INFO(1), REG_INFO(2), REG_INFO(4)); 265 // v1, a1. 266 PrintF("%26s\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 267 "", REG_INFO(3), REG_INFO(5)); 268 // a2. 269 PrintF("%26s\t%26s\t%3s: 0x%08x %10d\n", "", "", REG_INFO(6)); 270 // a3. 271 PrintF("%26s\t%26s\t%3s: 0x%08x %10d\n", "", "", REG_INFO(7)); 272 PrintF("\n"); 273 // t0-t7, s0-s7 274 for (int i = 0; i < 8; i++) { 275 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 276 REG_INFO(8+i), REG_INFO(16+i)); 277 } 278 PrintF("\n"); 279 // t8, k0, LO. 280 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 281 REG_INFO(24), REG_INFO(26), REG_INFO(32)); 282 // t9, k1, HI. 283 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 284 REG_INFO(25), REG_INFO(27), REG_INFO(33)); 285 // sp, fp, gp. 286 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 287 REG_INFO(29), REG_INFO(30), REG_INFO(28)); 288 // pc. 289 PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n", 290 REG_INFO(31), REG_INFO(34)); 291 292 #undef REG_INFO 293 #undef FPU_REG_INFO 294 } 295 296 297 void MipsDebugger::PrintAllRegsIncludingFPU() { 298 #define FPU_REG_INFO(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \ 299 GetFPURegisterValueInt(n+1), \ 300 GetFPURegisterValueInt(n), \ 301 GetFPURegisterValueDouble(n) 302 303 PrintAllRegs(); 304 305 PrintF("\n\n"); 306 // f0, f1, f2, ... f31. 307 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(0) ); 308 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(2) ); 309 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(4) ); 310 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(6) ); 311 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(8) ); 312 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(10)); 313 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(12)); 314 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(14)); 315 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(16)); 316 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(18)); 317 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(20)); 318 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(22)); 319 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(24)); 320 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(26)); 321 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(28)); 322 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(30)); 323 324 #undef REG_INFO 325 #undef FPU_REG_INFO 326 } 327 328 329 void MipsDebugger::Debug() { 330 intptr_t last_pc = -1; 331 bool done = false; 332 333 #define COMMAND_SIZE 63 334 #define ARG_SIZE 255 335 336 #define STR(a) #a 337 #define XSTR(a) STR(a) 338 339 char cmd[COMMAND_SIZE + 1]; 340 char arg1[ARG_SIZE + 1]; 341 char arg2[ARG_SIZE + 1]; 342 char* argv[3] = { cmd, arg1, arg2 }; 343 344 // Make sure to have a proper terminating character if reaching the limit. 345 cmd[COMMAND_SIZE] = 0; 346 arg1[ARG_SIZE] = 0; 347 arg2[ARG_SIZE] = 0; 348 349 // Undo all set breakpoints while running in the debugger shell. This will 350 // make them invisible to all commands. 351 UndoBreakpoints(); 352 353 while (!done && (sim_->get_pc() != Simulator::end_sim_pc)) { 354 if (last_pc != sim_->get_pc()) { 355 disasm::NameConverter converter; 356 disasm::Disassembler dasm(converter); 357 // Use a reasonably large buffer. 358 v8::internal::EmbeddedVector<char, 256> buffer; 359 dasm.InstructionDecode(buffer, 360 reinterpret_cast<byte*>(sim_->get_pc())); 361 PrintF(" 0x%08x %s\n", sim_->get_pc(), buffer.start()); 362 last_pc = sim_->get_pc(); 363 } 364 char* line = ReadLine("sim> "); 365 if (line == NULL) { 366 break; 367 } else { 368 char* last_input = sim_->last_debugger_input(); 369 if (strcmp(line, "\n") == 0 && last_input != NULL) { 370 line = last_input; 371 } else { 372 // Ownership is transferred to sim_; 373 sim_->set_last_debugger_input(line); 374 } 375 // Use sscanf to parse the individual parts of the command line. At the 376 // moment no command expects more than two parameters. 377 int argc = SScanF(line, 378 "%" XSTR(COMMAND_SIZE) "s " 379 "%" XSTR(ARG_SIZE) "s " 380 "%" XSTR(ARG_SIZE) "s", 381 cmd, arg1, arg2); 382 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 383 Instruction* instr = reinterpret_cast<Instruction*>(sim_->get_pc()); 384 if (!(instr->IsTrap()) || 385 instr->InstructionBits() == rtCallRedirInstr) { 386 sim_->InstructionDecode( 387 reinterpret_cast<Instruction*>(sim_->get_pc())); 388 } else { 389 // Allow si to jump over generated breakpoints. 390 PrintF("/!\\ Jumping over generated breakpoint.\n"); 391 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize); 392 } 393 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 394 // Execute the one instruction we broke at with breakpoints disabled. 395 sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc())); 396 // Leave the debugger shell. 397 done = true; 398 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 399 if (argc == 2) { 400 int32_t value; 401 float fvalue; 402 if (strcmp(arg1, "all") == 0) { 403 PrintAllRegs(); 404 } else if (strcmp(arg1, "allf") == 0) { 405 PrintAllRegsIncludingFPU(); 406 } else { 407 int regnum = Registers::Number(arg1); 408 int fpuregnum = FPURegisters::Number(arg1); 409 410 if (regnum != kInvalidRegister) { 411 value = GetRegisterValue(regnum); 412 PrintF("%s: 0x%08x %d \n", arg1, value, value); 413 } else if (fpuregnum != kInvalidFPURegister) { 414 if (fpuregnum % 2 == 1) { 415 value = GetFPURegisterValueInt(fpuregnum); 416 fvalue = GetFPURegisterValueFloat(fpuregnum); 417 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue); 418 } else { 419 double dfvalue; 420 int32_t lvalue1 = GetFPURegisterValueInt(fpuregnum); 421 int32_t lvalue2 = GetFPURegisterValueInt(fpuregnum + 1); 422 dfvalue = GetFPURegisterValueDouble(fpuregnum); 423 PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", 424 FPURegisters::Name(fpuregnum+1), 425 FPURegisters::Name(fpuregnum), 426 lvalue1, 427 lvalue2, 428 dfvalue); 429 } 430 } else { 431 PrintF("%s unrecognized\n", arg1); 432 } 433 } 434 } else { 435 if (argc == 3) { 436 if (strcmp(arg2, "single") == 0) { 437 int32_t value; 438 float fvalue; 439 int fpuregnum = FPURegisters::Number(arg1); 440 441 if (fpuregnum != kInvalidFPURegister) { 442 value = GetFPURegisterValueInt(fpuregnum); 443 fvalue = GetFPURegisterValueFloat(fpuregnum); 444 PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue); 445 } else { 446 PrintF("%s unrecognized\n", arg1); 447 } 448 } else { 449 PrintF("print <fpu register> single\n"); 450 } 451 } else { 452 PrintF("print <register> or print <fpu register> single\n"); 453 } 454 } 455 } else if ((strcmp(cmd, "po") == 0) 456 || (strcmp(cmd, "printobject") == 0)) { 457 if (argc == 2) { 458 int32_t value; 459 if (GetValue(arg1, &value)) { 460 Object* obj = reinterpret_cast<Object*>(value); 461 PrintF("%s: \n", arg1); 462 #ifdef DEBUG 463 obj->PrintLn(); 464 #else 465 obj->ShortPrint(); 466 PrintF("\n"); 467 #endif 468 } else { 469 PrintF("%s unrecognized\n", arg1); 470 } 471 } else { 472 PrintF("printobject <value>\n"); 473 } 474 } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) { 475 int32_t* cur = NULL; 476 int32_t* end = NULL; 477 int next_arg = 1; 478 479 if (strcmp(cmd, "stack") == 0) { 480 cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp)); 481 } else { // Command "mem". 482 int32_t value; 483 if (!GetValue(arg1, &value)) { 484 PrintF("%s unrecognized\n", arg1); 485 continue; 486 } 487 cur = reinterpret_cast<int32_t*>(value); 488 next_arg++; 489 } 490 491 int32_t words; 492 if (argc == next_arg) { 493 words = 10; 494 } else { 495 if (!GetValue(argv[next_arg], &words)) { 496 words = 10; 497 } 498 } 499 end = cur + words; 500 501 while (cur < end) { 502 PrintF(" 0x%08x: 0x%08x %10d", 503 reinterpret_cast<intptr_t>(cur), *cur, *cur); 504 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); 505 int value = *cur; 506 Heap* current_heap = v8::internal::Isolate::Current()->heap(); 507 if (((value & 1) == 0) || current_heap->Contains(obj)) { 508 PrintF(" ("); 509 if ((value & 1) == 0) { 510 PrintF("smi %d", value / 2); 511 } else { 512 obj->ShortPrint(); 513 } 514 PrintF(")"); 515 } 516 PrintF("\n"); 517 cur++; 518 } 519 520 } else if ((strcmp(cmd, "disasm") == 0) || 521 (strcmp(cmd, "dpc") == 0) || 522 (strcmp(cmd, "di") == 0)) { 523 disasm::NameConverter converter; 524 disasm::Disassembler dasm(converter); 525 // Use a reasonably large buffer. 526 v8::internal::EmbeddedVector<char, 256> buffer; 527 528 byte* cur = NULL; 529 byte* end = NULL; 530 531 if (argc == 1) { 532 cur = reinterpret_cast<byte*>(sim_->get_pc()); 533 end = cur + (10 * Instruction::kInstrSize); 534 } else if (argc == 2) { 535 int regnum = Registers::Number(arg1); 536 if (regnum != kInvalidRegister || strncmp(arg1, "0x", 2) == 0) { 537 // The argument is an address or a register name. 538 int32_t value; 539 if (GetValue(arg1, &value)) { 540 cur = reinterpret_cast<byte*>(value); 541 // Disassemble 10 instructions at <arg1>. 542 end = cur + (10 * Instruction::kInstrSize); 543 } 544 } else { 545 // The argument is the number of instructions. 546 int32_t value; 547 if (GetValue(arg1, &value)) { 548 cur = reinterpret_cast<byte*>(sim_->get_pc()); 549 // Disassemble <arg1> instructions. 550 end = cur + (value * Instruction::kInstrSize); 551 } 552 } 553 } else { 554 int32_t value1; 555 int32_t value2; 556 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { 557 cur = reinterpret_cast<byte*>(value1); 558 end = cur + (value2 * Instruction::kInstrSize); 559 } 560 } 561 562 while (cur < end) { 563 dasm.InstructionDecode(buffer, cur); 564 PrintF(" 0x%08x %s\n", 565 reinterpret_cast<intptr_t>(cur), buffer.start()); 566 cur += Instruction::kInstrSize; 567 } 568 } else if (strcmp(cmd, "gdb") == 0) { 569 PrintF("relinquishing control to gdb\n"); 570 v8::internal::OS::DebugBreak(); 571 PrintF("regaining control from gdb\n"); 572 } else if (strcmp(cmd, "break") == 0) { 573 if (argc == 2) { 574 int32_t value; 575 if (GetValue(arg1, &value)) { 576 if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) { 577 PrintF("setting breakpoint failed\n"); 578 } 579 } else { 580 PrintF("%s unrecognized\n", arg1); 581 } 582 } else { 583 PrintF("break <address>\n"); 584 } 585 } else if (strcmp(cmd, "del") == 0) { 586 if (!DeleteBreakpoint(NULL)) { 587 PrintF("deleting breakpoint failed\n"); 588 } 589 } else if (strcmp(cmd, "flags") == 0) { 590 PrintF("No flags on MIPS !\n"); 591 } else if (strcmp(cmd, "stop") == 0) { 592 int32_t value; 593 intptr_t stop_pc = sim_->get_pc() - 594 2 * Instruction::kInstrSize; 595 Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc); 596 Instruction* msg_address = 597 reinterpret_cast<Instruction*>(stop_pc + 598 Instruction::kInstrSize); 599 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) { 600 // Remove the current stop. 601 if (sim_->IsStopInstruction(stop_instr)) { 602 stop_instr->SetInstructionBits(kNopInstr); 603 msg_address->SetInstructionBits(kNopInstr); 604 } else { 605 PrintF("Not at debugger stop.\n"); 606 } 607 } else if (argc == 3) { 608 // Print information about all/the specified breakpoint(s). 609 if (strcmp(arg1, "info") == 0) { 610 if (strcmp(arg2, "all") == 0) { 611 PrintF("Stop information:\n"); 612 for (uint32_t i = kMaxWatchpointCode + 1; 613 i <= kMaxStopCode; 614 i++) { 615 sim_->PrintStopInfo(i); 616 } 617 } else if (GetValue(arg2, &value)) { 618 sim_->PrintStopInfo(value); 619 } else { 620 PrintF("Unrecognized argument.\n"); 621 } 622 } else if (strcmp(arg1, "enable") == 0) { 623 // Enable all/the specified breakpoint(s). 624 if (strcmp(arg2, "all") == 0) { 625 for (uint32_t i = kMaxWatchpointCode + 1; 626 i <= kMaxStopCode; 627 i++) { 628 sim_->EnableStop(i); 629 } 630 } else if (GetValue(arg2, &value)) { 631 sim_->EnableStop(value); 632 } else { 633 PrintF("Unrecognized argument.\n"); 634 } 635 } else if (strcmp(arg1, "disable") == 0) { 636 // Disable all/the specified breakpoint(s). 637 if (strcmp(arg2, "all") == 0) { 638 for (uint32_t i = kMaxWatchpointCode + 1; 639 i <= kMaxStopCode; 640 i++) { 641 sim_->DisableStop(i); 642 } 643 } else if (GetValue(arg2, &value)) { 644 sim_->DisableStop(value); 645 } else { 646 PrintF("Unrecognized argument.\n"); 647 } 648 } 649 } else { 650 PrintF("Wrong usage. Use help command for more information.\n"); 651 } 652 } else if ((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0)) { 653 // Print registers and disassemble. 654 PrintAllRegs(); 655 PrintF("\n"); 656 657 disasm::NameConverter converter; 658 disasm::Disassembler dasm(converter); 659 // Use a reasonably large buffer. 660 v8::internal::EmbeddedVector<char, 256> buffer; 661 662 byte* cur = NULL; 663 byte* end = NULL; 664 665 if (argc == 1) { 666 cur = reinterpret_cast<byte*>(sim_->get_pc()); 667 end = cur + (10 * Instruction::kInstrSize); 668 } else if (argc == 2) { 669 int32_t value; 670 if (GetValue(arg1, &value)) { 671 cur = reinterpret_cast<byte*>(value); 672 // no length parameter passed, assume 10 instructions 673 end = cur + (10 * Instruction::kInstrSize); 674 } 675 } else { 676 int32_t value1; 677 int32_t value2; 678 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { 679 cur = reinterpret_cast<byte*>(value1); 680 end = cur + (value2 * Instruction::kInstrSize); 681 } 682 } 683 684 while (cur < end) { 685 dasm.InstructionDecode(buffer, cur); 686 PrintF(" 0x%08x %s\n", 687 reinterpret_cast<intptr_t>(cur), buffer.start()); 688 cur += Instruction::kInstrSize; 689 } 690 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { 691 PrintF("cont\n"); 692 PrintF(" continue execution (alias 'c')\n"); 693 PrintF("stepi\n"); 694 PrintF(" step one instruction (alias 'si')\n"); 695 PrintF("print <register>\n"); 696 PrintF(" print register content (alias 'p')\n"); 697 PrintF(" use register name 'all' to print all registers\n"); 698 PrintF("printobject <register>\n"); 699 PrintF(" print an object from a register (alias 'po')\n"); 700 PrintF("stack [<words>]\n"); 701 PrintF(" dump stack content, default dump 10 words)\n"); 702 PrintF("mem <address> [<words>]\n"); 703 PrintF(" dump memory content, default dump 10 words)\n"); 704 PrintF("flags\n"); 705 PrintF(" print flags\n"); 706 PrintF("disasm [<instructions>]\n"); 707 PrintF("disasm [<address/register>]\n"); 708 PrintF("disasm [[<address/register>] <instructions>]\n"); 709 PrintF(" disassemble code, default is 10 instructions\n"); 710 PrintF(" from pc (alias 'di')\n"); 711 PrintF("gdb\n"); 712 PrintF(" enter gdb\n"); 713 PrintF("break <address>\n"); 714 PrintF(" set a break point on the address\n"); 715 PrintF("del\n"); 716 PrintF(" delete the breakpoint\n"); 717 PrintF("stop feature:\n"); 718 PrintF(" Description:\n"); 719 PrintF(" Stops are debug instructions inserted by\n"); 720 PrintF(" the Assembler::stop() function.\n"); 721 PrintF(" When hitting a stop, the Simulator will\n"); 722 PrintF(" stop and and give control to the Debugger.\n"); 723 PrintF(" All stop codes are watched:\n"); 724 PrintF(" - They can be enabled / disabled: the Simulator\n"); 725 PrintF(" will / won't stop when hitting them.\n"); 726 PrintF(" - The Simulator keeps track of how many times they \n"); 727 PrintF(" are met. (See the info command.) Going over a\n"); 728 PrintF(" disabled stop still increases its counter. \n"); 729 PrintF(" Commands:\n"); 730 PrintF(" stop info all/<code> : print infos about number <code>\n"); 731 PrintF(" or all stop(s).\n"); 732 PrintF(" stop enable/disable all/<code> : enables / disables\n"); 733 PrintF(" all or number <code> stop(s)\n"); 734 PrintF(" stop unstop\n"); 735 PrintF(" ignore the stop instruction at the current location\n"); 736 PrintF(" from now on\n"); 737 } else { 738 PrintF("Unknown command: %s\n", cmd); 739 } 740 } 741 } 742 743 // Add all the breakpoints back to stop execution and enter the debugger 744 // shell when hit. 745 RedoBreakpoints(); 746 747 #undef COMMAND_SIZE 748 #undef ARG_SIZE 749 750 #undef STR 751 #undef XSTR 752 } 753 754 755 static bool ICacheMatch(void* one, void* two) { 756 ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0); 757 ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); 758 return one == two; 759 } 760 761 762 static uint32_t ICacheHash(void* key) { 763 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; 764 } 765 766 767 static bool AllOnOnePage(uintptr_t start, int size) { 768 intptr_t start_page = (start & ~CachePage::kPageMask); 769 intptr_t end_page = ((start + size) & ~CachePage::kPageMask); 770 return start_page == end_page; 771 } 772 773 774 void Simulator::set_last_debugger_input(char* input) { 775 DeleteArray(last_debugger_input_); 776 last_debugger_input_ = input; 777 } 778 779 780 void Simulator::FlushICache(v8::internal::HashMap* i_cache, 781 void* start_addr, 782 size_t size) { 783 intptr_t start = reinterpret_cast<intptr_t>(start_addr); 784 int intra_line = (start & CachePage::kLineMask); 785 start -= intra_line; 786 size += intra_line; 787 size = ((size - 1) | CachePage::kLineMask) + 1; 788 int offset = (start & CachePage::kPageMask); 789 while (!AllOnOnePage(start, size - 1)) { 790 int bytes_to_flush = CachePage::kPageSize - offset; 791 FlushOnePage(i_cache, start, bytes_to_flush); 792 start += bytes_to_flush; 793 size -= bytes_to_flush; 794 ASSERT_EQ(0, start & CachePage::kPageMask); 795 offset = 0; 796 } 797 if (size != 0) { 798 FlushOnePage(i_cache, start, size); 799 } 800 } 801 802 803 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) { 804 v8::internal::HashMap::Entry* entry = i_cache->Lookup(page, 805 ICacheHash(page), 806 true); 807 if (entry->value == NULL) { 808 CachePage* new_page = new CachePage(); 809 entry->value = new_page; 810 } 811 return reinterpret_cast<CachePage*>(entry->value); 812 } 813 814 815 // Flush from start up to and not including start + size. 816 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, 817 intptr_t start, 818 int size) { 819 ASSERT(size <= CachePage::kPageSize); 820 ASSERT(AllOnOnePage(start, size - 1)); 821 ASSERT((start & CachePage::kLineMask) == 0); 822 ASSERT((size & CachePage::kLineMask) == 0); 823 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); 824 int offset = (start & CachePage::kPageMask); 825 CachePage* cache_page = GetCachePage(i_cache, page); 826 char* valid_bytemap = cache_page->ValidityByte(offset); 827 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); 828 } 829 830 831 void Simulator::CheckICache(v8::internal::HashMap* i_cache, 832 Instruction* instr) { 833 intptr_t address = reinterpret_cast<intptr_t>(instr); 834 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); 835 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); 836 int offset = (address & CachePage::kPageMask); 837 CachePage* cache_page = GetCachePage(i_cache, page); 838 char* cache_valid_byte = cache_page->ValidityByte(offset); 839 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); 840 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); 841 if (cache_hit) { 842 // Check that the data in memory matches the contents of the I-cache. 843 CHECK_EQ(0, memcmp(reinterpret_cast<void*>(instr), 844 cache_page->CachedData(offset), 845 Instruction::kInstrSize)); 846 } else { 847 // Cache miss. Load memory into the cache. 848 memcpy(cached_line, line, CachePage::kLineLength); 849 *cache_valid_byte = CachePage::LINE_VALID; 850 } 851 } 852 853 854 void Simulator::Initialize(Isolate* isolate) { 855 if (isolate->simulator_initialized()) return; 856 isolate->set_simulator_initialized(true); 857 ::v8::internal::ExternalReference::set_redirector(isolate, 858 &RedirectExternalReference); 859 } 860 861 862 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) { 863 i_cache_ = isolate_->simulator_i_cache(); 864 if (i_cache_ == NULL) { 865 i_cache_ = new v8::internal::HashMap(&ICacheMatch); 866 isolate_->set_simulator_i_cache(i_cache_); 867 } 868 Initialize(isolate); 869 // Set up simulator support first. Some of this information is needed to 870 // setup the architecture state. 871 stack_ = reinterpret_cast<char*>(malloc(stack_size_)); 872 pc_modified_ = false; 873 icount_ = 0; 874 break_count_ = 0; 875 break_pc_ = NULL; 876 break_instr_ = 0; 877 878 // Set up architecture state. 879 // All registers are initialized to zero to start with. 880 for (int i = 0; i < kNumSimuRegisters; i++) { 881 registers_[i] = 0; 882 } 883 for (int i = 0; i < kNumFPURegisters; i++) { 884 FPUregisters_[i] = 0; 885 } 886 FCSR_ = 0; 887 888 // The sp is initialized to point to the bottom (high address) of the 889 // allocated stack area. To be safe in potential stack underflows we leave 890 // some buffer below. 891 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64; 892 // The ra and pc are initialized to a known bad value that will cause an 893 // access violation if the simulator ever tries to execute it. 894 registers_[pc] = bad_ra; 895 registers_[ra] = bad_ra; 896 InitializeCoverage(); 897 for (int i = 0; i < kNumExceptions; i++) { 898 exceptions[i] = 0; 899 } 900 901 last_debugger_input_ = NULL; 902 } 903 904 905 Simulator::~Simulator() { 906 } 907 908 909 // When the generated code calls an external reference we need to catch that in 910 // the simulator. The external reference will be a function compiled for the 911 // host architecture. We need to call that function instead of trying to 912 // execute it with the simulator. We do that by redirecting the external 913 // reference to a swi (software-interrupt) instruction that is handled by 914 // the simulator. We write the original destination of the jump just at a known 915 // offset from the swi instruction so the simulator knows what to call. 916 class Redirection { 917 public: 918 Redirection(void* external_function, ExternalReference::Type type) 919 : external_function_(external_function), 920 swi_instruction_(rtCallRedirInstr), 921 type_(type), 922 next_(NULL) { 923 Isolate* isolate = Isolate::Current(); 924 next_ = isolate->simulator_redirection(); 925 Simulator::current(isolate)-> 926 FlushICache(isolate->simulator_i_cache(), 927 reinterpret_cast<void*>(&swi_instruction_), 928 Instruction::kInstrSize); 929 isolate->set_simulator_redirection(this); 930 } 931 932 void* address_of_swi_instruction() { 933 return reinterpret_cast<void*>(&swi_instruction_); 934 } 935 936 void* external_function() { return external_function_; } 937 ExternalReference::Type type() { return type_; } 938 939 static Redirection* Get(void* external_function, 940 ExternalReference::Type type) { 941 Isolate* isolate = Isolate::Current(); 942 Redirection* current = isolate->simulator_redirection(); 943 for (; current != NULL; current = current->next_) { 944 if (current->external_function_ == external_function) return current; 945 } 946 return new Redirection(external_function, type); 947 } 948 949 static Redirection* FromSwiInstruction(Instruction* swi_instruction) { 950 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 951 char* addr_of_redirection = 952 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_); 953 return reinterpret_cast<Redirection*>(addr_of_redirection); 954 } 955 956 static void* ReverseRedirection(int32_t reg) { 957 Redirection* redirection = FromSwiInstruction( 958 reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg))); 959 return redirection->external_function(); 960 } 961 962 private: 963 void* external_function_; 964 uint32_t swi_instruction_; 965 ExternalReference::Type type_; 966 Redirection* next_; 967 }; 968 969 970 void* Simulator::RedirectExternalReference(void* external_function, 971 ExternalReference::Type type) { 972 Redirection* redirection = Redirection::Get(external_function, type); 973 return redirection->address_of_swi_instruction(); 974 } 975 976 977 // Get the active Simulator for the current thread. 978 Simulator* Simulator::current(Isolate* isolate) { 979 v8::internal::Isolate::PerIsolateThreadData* isolate_data = 980 isolate->FindOrAllocatePerThreadDataForThisThread(); 981 ASSERT(isolate_data != NULL); 982 ASSERT(isolate_data != NULL); 983 984 Simulator* sim = isolate_data->simulator(); 985 if (sim == NULL) { 986 // TODO(146): delete the simulator object when a thread/isolate goes away. 987 sim = new Simulator(isolate); 988 isolate_data->set_simulator(sim); 989 } 990 return sim; 991 } 992 993 994 // Sets the register in the architecture state. It will also deal with updating 995 // Simulator internal state for special registers such as PC. 996 void Simulator::set_register(int reg, int32_t value) { 997 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); 998 if (reg == pc) { 999 pc_modified_ = true; 1000 } 1001 1002 // Zero register always holds 0. 1003 registers_[reg] = (reg == 0) ? 0 : value; 1004 } 1005 1006 1007 void Simulator::set_dw_register(int reg, const int* dbl) { 1008 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); 1009 registers_[reg] = dbl[0]; 1010 registers_[reg + 1] = dbl[1]; 1011 } 1012 1013 1014 void Simulator::set_fpu_register(int fpureg, int32_t value) { 1015 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1016 FPUregisters_[fpureg] = value; 1017 } 1018 1019 1020 void Simulator::set_fpu_register_float(int fpureg, float value) { 1021 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1022 *BitCast<float*>(&FPUregisters_[fpureg]) = value; 1023 } 1024 1025 1026 void Simulator::set_fpu_register_double(int fpureg, double value) { 1027 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1028 *BitCast<double*>(&FPUregisters_[fpureg]) = value; 1029 } 1030 1031 1032 // Get the register from the architecture state. This function does handle 1033 // the special case of accessing the PC register. 1034 int32_t Simulator::get_register(int reg) const { 1035 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); 1036 if (reg == 0) 1037 return 0; 1038 else 1039 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); 1040 } 1041 1042 1043 double Simulator::get_double_from_register_pair(int reg) { 1044 ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); 1045 1046 double dm_val = 0.0; 1047 // Read the bits from the unsigned integer register_[] array 1048 // into the double precision floating point value and return it. 1049 char buffer[2 * sizeof(registers_[0])]; 1050 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); 1051 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); 1052 return(dm_val); 1053 } 1054 1055 1056 int32_t Simulator::get_fpu_register(int fpureg) const { 1057 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1058 return FPUregisters_[fpureg]; 1059 } 1060 1061 1062 int64_t Simulator::get_fpu_register_long(int fpureg) const { 1063 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1064 return *BitCast<int64_t*>( 1065 const_cast<int32_t*>(&FPUregisters_[fpureg])); 1066 } 1067 1068 1069 float Simulator::get_fpu_register_float(int fpureg) const { 1070 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); 1071 return *BitCast<float*>( 1072 const_cast<int32_t*>(&FPUregisters_[fpureg])); 1073 } 1074 1075 1076 double Simulator::get_fpu_register_double(int fpureg) const { 1077 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1078 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg])); 1079 } 1080 1081 1082 // Runtime FP routines take up to two double arguments and zero 1083 // or one integer arguments. All are constructed here, 1084 // from a0-a3 or f12 and f14. 1085 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { 1086 if (!IsMipsSoftFloatABI) { 1087 *x = get_fpu_register_double(12); 1088 *y = get_fpu_register_double(14); 1089 *z = get_register(a2); 1090 } else { 1091 // We use a char buffer to get around the strict-aliasing rules which 1092 // otherwise allow the compiler to optimize away the copy. 1093 char buffer[sizeof(*x)]; 1094 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); 1095 1096 // Registers a0 and a1 -> x. 1097 reg_buffer[0] = get_register(a0); 1098 reg_buffer[1] = get_register(a1); 1099 memcpy(x, buffer, sizeof(buffer)); 1100 // Registers a2 and a3 -> y. 1101 reg_buffer[0] = get_register(a2); 1102 reg_buffer[1] = get_register(a3); 1103 memcpy(y, buffer, sizeof(buffer)); 1104 // Register 2 -> z. 1105 reg_buffer[0] = get_register(a2); 1106 memcpy(z, buffer, sizeof(*z)); 1107 } 1108 } 1109 1110 1111 // The return value is either in v0/v1 or f0. 1112 void Simulator::SetFpResult(const double& result) { 1113 if (!IsMipsSoftFloatABI) { 1114 set_fpu_register_double(0, result); 1115 } else { 1116 char buffer[2 * sizeof(registers_[0])]; 1117 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); 1118 memcpy(buffer, &result, sizeof(buffer)); 1119 // Copy result to v0 and v1. 1120 set_register(v0, reg_buffer[0]); 1121 set_register(v1, reg_buffer[1]); 1122 } 1123 } 1124 1125 1126 // Helper functions for setting and testing the FCSR register's bits. 1127 void Simulator::set_fcsr_bit(uint32_t cc, bool value) { 1128 if (value) { 1129 FCSR_ |= (1 << cc); 1130 } else { 1131 FCSR_ &= ~(1 << cc); 1132 } 1133 } 1134 1135 1136 bool Simulator::test_fcsr_bit(uint32_t cc) { 1137 return FCSR_ & (1 << cc); 1138 } 1139 1140 1141 // Sets the rounding error codes in FCSR based on the result of the rounding. 1142 // Returns true if the operation was invalid. 1143 bool Simulator::set_fcsr_round_error(double original, double rounded) { 1144 bool ret = false; 1145 1146 if (!std::isfinite(original) || !std::isfinite(rounded)) { 1147 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1148 ret = true; 1149 } 1150 1151 if (original != rounded) { 1152 set_fcsr_bit(kFCSRInexactFlagBit, true); 1153 } 1154 1155 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { 1156 set_fcsr_bit(kFCSRUnderflowFlagBit, true); 1157 ret = true; 1158 } 1159 1160 if (rounded > INT_MAX || rounded < INT_MIN) { 1161 set_fcsr_bit(kFCSROverflowFlagBit, true); 1162 // The reference is not really clear but it seems this is required: 1163 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1164 ret = true; 1165 } 1166 1167 return ret; 1168 } 1169 1170 1171 // Raw access to the PC register. 1172 void Simulator::set_pc(int32_t value) { 1173 pc_modified_ = true; 1174 registers_[pc] = value; 1175 } 1176 1177 1178 bool Simulator::has_bad_pc() const { 1179 return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc)); 1180 } 1181 1182 1183 // Raw access to the PC register without the special adjustment when reading. 1184 int32_t Simulator::get_pc() const { 1185 return registers_[pc]; 1186 } 1187 1188 1189 // The MIPS cannot do unaligned reads and writes. On some MIPS platforms an 1190 // interrupt is caused. On others it does a funky rotation thing. For now we 1191 // simply disallow unaligned reads, but at some point we may want to move to 1192 // emulating the rotate behaviour. Note that simulator runs have the runtime 1193 // system running directly on the host system and only generated code is 1194 // executed in the simulator. Since the host is typically IA32 we will not 1195 // get the correct MIPS-like behaviour on unaligned accesses. 1196 1197 int Simulator::ReadW(int32_t addr, Instruction* instr) { 1198 if (addr >=0 && addr < 0x400) { 1199 // This has to be a NULL-dereference, drop into debugger. 1200 PrintF("Memory read from bad address: 0x%08x, pc=0x%08x\n", 1201 addr, reinterpret_cast<intptr_t>(instr)); 1202 MipsDebugger dbg(this); 1203 dbg.Debug(); 1204 } 1205 if ((addr & kPointerAlignmentMask) == 0) { 1206 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1207 return *ptr; 1208 } 1209 PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1210 addr, 1211 reinterpret_cast<intptr_t>(instr)); 1212 MipsDebugger dbg(this); 1213 dbg.Debug(); 1214 return 0; 1215 } 1216 1217 1218 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { 1219 if (addr >= 0 && addr < 0x400) { 1220 // This has to be a NULL-dereference, drop into debugger. 1221 PrintF("Memory write to bad address: 0x%08x, pc=0x%08x\n", 1222 addr, reinterpret_cast<intptr_t>(instr)); 1223 MipsDebugger dbg(this); 1224 dbg.Debug(); 1225 } 1226 if ((addr & kPointerAlignmentMask) == 0) { 1227 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1228 *ptr = value; 1229 return; 1230 } 1231 PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1232 addr, 1233 reinterpret_cast<intptr_t>(instr)); 1234 MipsDebugger dbg(this); 1235 dbg.Debug(); 1236 } 1237 1238 1239 double Simulator::ReadD(int32_t addr, Instruction* instr) { 1240 if ((addr & kDoubleAlignmentMask) == 0) { 1241 double* ptr = reinterpret_cast<double*>(addr); 1242 return *ptr; 1243 } 1244 PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1245 addr, 1246 reinterpret_cast<intptr_t>(instr)); 1247 OS::Abort(); 1248 return 0; 1249 } 1250 1251 1252 void Simulator::WriteD(int32_t addr, double value, Instruction* instr) { 1253 if ((addr & kDoubleAlignmentMask) == 0) { 1254 double* ptr = reinterpret_cast<double*>(addr); 1255 *ptr = value; 1256 return; 1257 } 1258 PrintF("Unaligned (double) write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1259 addr, 1260 reinterpret_cast<intptr_t>(instr)); 1261 OS::Abort(); 1262 } 1263 1264 1265 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) { 1266 if ((addr & 1) == 0) { 1267 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1268 return *ptr; 1269 } 1270 PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1271 addr, 1272 reinterpret_cast<intptr_t>(instr)); 1273 OS::Abort(); 1274 return 0; 1275 } 1276 1277 1278 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) { 1279 if ((addr & 1) == 0) { 1280 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1281 return *ptr; 1282 } 1283 PrintF("Unaligned signed halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1284 addr, 1285 reinterpret_cast<intptr_t>(instr)); 1286 OS::Abort(); 1287 return 0; 1288 } 1289 1290 1291 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) { 1292 if ((addr & 1) == 0) { 1293 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1294 *ptr = value; 1295 return; 1296 } 1297 PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1298 addr, 1299 reinterpret_cast<intptr_t>(instr)); 1300 OS::Abort(); 1301 } 1302 1303 1304 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) { 1305 if ((addr & 1) == 0) { 1306 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1307 *ptr = value; 1308 return; 1309 } 1310 PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1311 addr, 1312 reinterpret_cast<intptr_t>(instr)); 1313 OS::Abort(); 1314 } 1315 1316 1317 uint32_t Simulator::ReadBU(int32_t addr) { 1318 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1319 return *ptr & 0xff; 1320 } 1321 1322 1323 int32_t Simulator::ReadB(int32_t addr) { 1324 int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1325 return *ptr; 1326 } 1327 1328 1329 void Simulator::WriteB(int32_t addr, uint8_t value) { 1330 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1331 *ptr = value; 1332 } 1333 1334 1335 void Simulator::WriteB(int32_t addr, int8_t value) { 1336 int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1337 *ptr = value; 1338 } 1339 1340 1341 // Returns the limit of the stack area to enable checking for stack overflows. 1342 uintptr_t Simulator::StackLimit() const { 1343 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when 1344 // pushing values. 1345 return reinterpret_cast<uintptr_t>(stack_) + 1024; 1346 } 1347 1348 1349 // Unsupported instructions use Format to print an error and stop execution. 1350 void Simulator::Format(Instruction* instr, const char* format) { 1351 PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n", 1352 reinterpret_cast<intptr_t>(instr), format); 1353 UNIMPLEMENTED_MIPS(); 1354 } 1355 1356 1357 // Calls into the V8 runtime are based on this very simple interface. 1358 // Note: To be able to return two values from some calls the code in runtime.cc 1359 // uses the ObjectPair which is essentially two 32-bit values stuffed into a 1360 // 64-bit value. With the code below we assume that all runtime calls return 1361 // 64 bits of result. If they don't, the v1 result register contains a bogus 1362 // value, which is fine because it is caller-saved. 1363 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, 1364 int32_t arg1, 1365 int32_t arg2, 1366 int32_t arg3, 1367 int32_t arg4, 1368 int32_t arg5); 1369 1370 // These prototypes handle the four types of FP calls. 1371 typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1); 1372 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); 1373 typedef double (*SimulatorRuntimeFPCall)(double darg0); 1374 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0); 1375 1376 // This signature supports direct call in to API function native callback 1377 // (refer to InvocationCallback in v8.h). 1378 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0); 1379 typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, void* arg1); 1380 1381 // This signature supports direct call to accessor getter callback. 1382 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1); 1383 typedef void (*SimulatorRuntimeProfilingGetterCall)( 1384 int32_t arg0, int32_t arg1, void* arg2); 1385 1386 // Software interrupt instructions are used by the simulator to call into the 1387 // C-based V8 runtime. They are also used for debugging with simulator. 1388 void Simulator::SoftwareInterrupt(Instruction* instr) { 1389 // There are several instructions that could get us here, 1390 // the break_ instruction, or several variants of traps. All 1391 // Are "SPECIAL" class opcode, and are distinuished by function. 1392 int32_t func = instr->FunctionFieldRaw(); 1393 uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1; 1394 1395 // We first check if we met a call_rt_redirected. 1396 if (instr->InstructionBits() == rtCallRedirInstr) { 1397 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1398 int32_t arg0 = get_register(a0); 1399 int32_t arg1 = get_register(a1); 1400 int32_t arg2 = get_register(a2); 1401 int32_t arg3 = get_register(a3); 1402 1403 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); 1404 // Args 4 and 5 are on the stack after the reserved space for args 0..3. 1405 int32_t arg4 = stack_pointer[4]; 1406 int32_t arg5 = stack_pointer[5]; 1407 1408 bool fp_call = 1409 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || 1410 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || 1411 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || 1412 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); 1413 1414 if (!IsMipsSoftFloatABI) { 1415 // With the hard floating point calling convention, double 1416 // arguments are passed in FPU registers. Fetch the arguments 1417 // from there and call the builtin using soft floating point 1418 // convention. 1419 switch (redirection->type()) { 1420 case ExternalReference::BUILTIN_FP_FP_CALL: 1421 case ExternalReference::BUILTIN_COMPARE_CALL: 1422 arg0 = get_fpu_register(f12); 1423 arg1 = get_fpu_register(f13); 1424 arg2 = get_fpu_register(f14); 1425 arg3 = get_fpu_register(f15); 1426 break; 1427 case ExternalReference::BUILTIN_FP_CALL: 1428 arg0 = get_fpu_register(f12); 1429 arg1 = get_fpu_register(f13); 1430 break; 1431 case ExternalReference::BUILTIN_FP_INT_CALL: 1432 arg0 = get_fpu_register(f12); 1433 arg1 = get_fpu_register(f13); 1434 arg2 = get_register(a2); 1435 break; 1436 default: 1437 break; 1438 } 1439 } 1440 1441 // This is dodgy but it works because the C entry stubs are never moved. 1442 // See comment in codegen-arm.cc and bug 1242173. 1443 int32_t saved_ra = get_register(ra); 1444 1445 intptr_t external = 1446 reinterpret_cast<intptr_t>(redirection->external_function()); 1447 1448 // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware 1449 // FPU, or gcc soft-float routines. Hardware FPU is simulated in this 1450 // simulator. Soft-float has additional abstraction of ExternalReference, 1451 // to support serialization. 1452 if (fp_call) { 1453 double dval0, dval1; // one or two double parameters 1454 int32_t ival; // zero or one integer parameters 1455 int64_t iresult = 0; // integer return value 1456 double dresult = 0; // double return value 1457 GetFpArgs(&dval0, &dval1, &ival); 1458 SimulatorRuntimeCall generic_target = 1459 reinterpret_cast<SimulatorRuntimeCall>(external); 1460 if (::v8::internal::FLAG_trace_sim) { 1461 switch (redirection->type()) { 1462 case ExternalReference::BUILTIN_FP_FP_CALL: 1463 case ExternalReference::BUILTIN_COMPARE_CALL: 1464 PrintF("Call to host function at %p with args %f, %f", 1465 FUNCTION_ADDR(generic_target), dval0, dval1); 1466 break; 1467 case ExternalReference::BUILTIN_FP_CALL: 1468 PrintF("Call to host function at %p with arg %f", 1469 FUNCTION_ADDR(generic_target), dval0); 1470 break; 1471 case ExternalReference::BUILTIN_FP_INT_CALL: 1472 PrintF("Call to host function at %p with args %f, %d", 1473 FUNCTION_ADDR(generic_target), dval0, ival); 1474 break; 1475 default: 1476 UNREACHABLE(); 1477 break; 1478 } 1479 } 1480 switch (redirection->type()) { 1481 case ExternalReference::BUILTIN_COMPARE_CALL: { 1482 SimulatorRuntimeCompareCall target = 1483 reinterpret_cast<SimulatorRuntimeCompareCall>(external); 1484 iresult = target(dval0, dval1); 1485 set_register(v0, static_cast<int32_t>(iresult)); 1486 set_register(v1, static_cast<int32_t>(iresult >> 32)); 1487 break; 1488 } 1489 case ExternalReference::BUILTIN_FP_FP_CALL: { 1490 SimulatorRuntimeFPFPCall target = 1491 reinterpret_cast<SimulatorRuntimeFPFPCall>(external); 1492 dresult = target(dval0, dval1); 1493 SetFpResult(dresult); 1494 break; 1495 } 1496 case ExternalReference::BUILTIN_FP_CALL: { 1497 SimulatorRuntimeFPCall target = 1498 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1499 dresult = target(dval0); 1500 SetFpResult(dresult); 1501 break; 1502 } 1503 case ExternalReference::BUILTIN_FP_INT_CALL: { 1504 SimulatorRuntimeFPIntCall target = 1505 reinterpret_cast<SimulatorRuntimeFPIntCall>(external); 1506 dresult = target(dval0, ival); 1507 SetFpResult(dresult); 1508 break; 1509 } 1510 default: 1511 UNREACHABLE(); 1512 break; 1513 } 1514 if (::v8::internal::FLAG_trace_sim) { 1515 switch (redirection->type()) { 1516 case ExternalReference::BUILTIN_COMPARE_CALL: 1517 PrintF("Returned %08x\n", static_cast<int32_t>(iresult)); 1518 break; 1519 case ExternalReference::BUILTIN_FP_FP_CALL: 1520 case ExternalReference::BUILTIN_FP_CALL: 1521 case ExternalReference::BUILTIN_FP_INT_CALL: 1522 PrintF("Returned %f\n", dresult); 1523 break; 1524 default: 1525 UNREACHABLE(); 1526 break; 1527 } 1528 } 1529 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { 1530 if (::v8::internal::FLAG_trace_sim) { 1531 PrintF("Call to host function at %p args %08x\n", 1532 reinterpret_cast<void*>(external), arg0); 1533 } 1534 SimulatorRuntimeDirectApiCall target = 1535 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 1536 target(arg0); 1537 } else if ( 1538 redirection->type() == ExternalReference::PROFILING_API_CALL) { 1539 if (::v8::internal::FLAG_trace_sim) { 1540 PrintF("Call to host function at %p args %08x %08x\n", 1541 reinterpret_cast<void*>(external), arg0, arg1); 1542 } 1543 SimulatorRuntimeProfilingApiCall target = 1544 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); 1545 target(arg0, Redirection::ReverseRedirection(arg1)); 1546 } else if ( 1547 redirection->type() == ExternalReference::DIRECT_GETTER_CALL) { 1548 if (::v8::internal::FLAG_trace_sim) { 1549 PrintF("Call to host function at %p args %08x %08x\n", 1550 reinterpret_cast<void*>(external), arg0, arg1); 1551 } 1552 SimulatorRuntimeDirectGetterCall target = 1553 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); 1554 target(arg0, arg1); 1555 } else if ( 1556 redirection->type() == ExternalReference::PROFILING_GETTER_CALL) { 1557 if (::v8::internal::FLAG_trace_sim) { 1558 PrintF("Call to host function at %p args %08x %08x %08x\n", 1559 reinterpret_cast<void*>(external), arg0, arg1, arg2); 1560 } 1561 SimulatorRuntimeProfilingGetterCall target = 1562 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external); 1563 target(arg0, arg1, Redirection::ReverseRedirection(arg2)); 1564 } else { 1565 SimulatorRuntimeCall target = 1566 reinterpret_cast<SimulatorRuntimeCall>(external); 1567 if (::v8::internal::FLAG_trace_sim) { 1568 PrintF( 1569 "Call to host function at %p " 1570 "args %08x, %08x, %08x, %08x, %08x, %08x\n", 1571 FUNCTION_ADDR(target), 1572 arg0, 1573 arg1, 1574 arg2, 1575 arg3, 1576 arg4, 1577 arg5); 1578 } 1579 int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5); 1580 set_register(v0, static_cast<int32_t>(result)); 1581 set_register(v1, static_cast<int32_t>(result >> 32)); 1582 } 1583 if (::v8::internal::FLAG_trace_sim) { 1584 PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0)); 1585 } 1586 set_register(ra, saved_ra); 1587 set_pc(get_register(ra)); 1588 1589 } else if (func == BREAK && code <= kMaxStopCode) { 1590 if (IsWatchpoint(code)) { 1591 PrintWatchpoint(code); 1592 } else { 1593 IncreaseStopCounter(code); 1594 HandleStop(code, instr); 1595 } 1596 } else { 1597 // All remaining break_ codes, and all traps are handled here. 1598 MipsDebugger dbg(this); 1599 dbg.Debug(); 1600 } 1601 } 1602 1603 1604 // Stop helper functions. 1605 bool Simulator::IsWatchpoint(uint32_t code) { 1606 return (code <= kMaxWatchpointCode); 1607 } 1608 1609 1610 void Simulator::PrintWatchpoint(uint32_t code) { 1611 MipsDebugger dbg(this); 1612 ++break_count_; 1613 PrintF("\n---- break %d marker: %3d (instr count: %8d) ----------" 1614 "----------------------------------", 1615 code, break_count_, icount_); 1616 dbg.PrintAllRegs(); // Print registers and continue running. 1617 } 1618 1619 1620 void Simulator::HandleStop(uint32_t code, Instruction* instr) { 1621 // Stop if it is enabled, otherwise go on jumping over the stop 1622 // and the message address. 1623 if (IsEnabledStop(code)) { 1624 MipsDebugger dbg(this); 1625 dbg.Stop(instr); 1626 } else { 1627 set_pc(get_pc() + 2 * Instruction::kInstrSize); 1628 } 1629 } 1630 1631 1632 bool Simulator::IsStopInstruction(Instruction* instr) { 1633 int32_t func = instr->FunctionFieldRaw(); 1634 uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6)); 1635 return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode; 1636 } 1637 1638 1639 bool Simulator::IsEnabledStop(uint32_t code) { 1640 ASSERT(code <= kMaxStopCode); 1641 ASSERT(code > kMaxWatchpointCode); 1642 return !(watched_stops_[code].count & kStopDisabledBit); 1643 } 1644 1645 1646 void Simulator::EnableStop(uint32_t code) { 1647 if (!IsEnabledStop(code)) { 1648 watched_stops_[code].count &= ~kStopDisabledBit; 1649 } 1650 } 1651 1652 1653 void Simulator::DisableStop(uint32_t code) { 1654 if (IsEnabledStop(code)) { 1655 watched_stops_[code].count |= kStopDisabledBit; 1656 } 1657 } 1658 1659 1660 void Simulator::IncreaseStopCounter(uint32_t code) { 1661 ASSERT(code <= kMaxStopCode); 1662 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { 1663 PrintF("Stop counter for code %i has overflowed.\n" 1664 "Enabling this code and reseting the counter to 0.\n", code); 1665 watched_stops_[code].count = 0; 1666 EnableStop(code); 1667 } else { 1668 watched_stops_[code].count++; 1669 } 1670 } 1671 1672 1673 // Print a stop status. 1674 void Simulator::PrintStopInfo(uint32_t code) { 1675 if (code <= kMaxWatchpointCode) { 1676 PrintF("That is a watchpoint, not a stop.\n"); 1677 return; 1678 } else if (code > kMaxStopCode) { 1679 PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1); 1680 return; 1681 } 1682 const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled"; 1683 int32_t count = watched_stops_[code].count & ~kStopDisabledBit; 1684 // Don't print the state of unused breakpoints. 1685 if (count != 0) { 1686 if (watched_stops_[code].desc) { 1687 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", 1688 code, code, state, count, watched_stops_[code].desc); 1689 } else { 1690 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", 1691 code, code, state, count); 1692 } 1693 } 1694 } 1695 1696 1697 void Simulator::SignalExceptions() { 1698 for (int i = 1; i < kNumExceptions; i++) { 1699 if (exceptions[i] != 0) { 1700 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i); 1701 } 1702 } 1703 } 1704 1705 1706 // Handle execution based on instruction types. 1707 1708 void Simulator::ConfigureTypeRegister(Instruction* instr, 1709 int32_t* alu_out, 1710 int64_t* i64hilo, 1711 uint64_t* u64hilo, 1712 int32_t* next_pc, 1713 int32_t* return_addr_reg, 1714 bool* do_interrupt) { 1715 // Every local variable declared here needs to be const. 1716 // This is to make sure that changed values are sent back to 1717 // DecodeTypeRegister correctly. 1718 1719 // Instruction fields. 1720 const Opcode op = instr->OpcodeFieldRaw(); 1721 const int32_t rs_reg = instr->RsValue(); 1722 const int32_t rs = get_register(rs_reg); 1723 const uint32_t rs_u = static_cast<uint32_t>(rs); 1724 const int32_t rt_reg = instr->RtValue(); 1725 const int32_t rt = get_register(rt_reg); 1726 const uint32_t rt_u = static_cast<uint32_t>(rt); 1727 const int32_t rd_reg = instr->RdValue(); 1728 const uint32_t sa = instr->SaValue(); 1729 1730 const int32_t fs_reg = instr->FsValue(); 1731 1732 1733 // ---------- Configuration. 1734 switch (op) { 1735 case COP1: // Coprocessor instructions. 1736 switch (instr->RsFieldRaw()) { 1737 case BC1: // Handled in DecodeTypeImmed, should never come here. 1738 UNREACHABLE(); 1739 break; 1740 case CFC1: 1741 // At the moment only FCSR is supported. 1742 ASSERT(fs_reg == kFCSRRegister); 1743 *alu_out = FCSR_; 1744 break; 1745 case MFC1: 1746 *alu_out = get_fpu_register(fs_reg); 1747 break; 1748 case MFHC1: 1749 UNIMPLEMENTED_MIPS(); 1750 break; 1751 case CTC1: 1752 case MTC1: 1753 case MTHC1: 1754 // Do the store in the execution step. 1755 break; 1756 case S: 1757 case D: 1758 case W: 1759 case L: 1760 case PS: 1761 // Do everything in the execution step. 1762 break; 1763 default: 1764 UNIMPLEMENTED_MIPS(); 1765 } 1766 break; 1767 case COP1X: 1768 break; 1769 case SPECIAL: 1770 switch (instr->FunctionFieldRaw()) { 1771 case JR: 1772 case JALR: 1773 *next_pc = get_register(instr->RsValue()); 1774 *return_addr_reg = instr->RdValue(); 1775 break; 1776 case SLL: 1777 *alu_out = rt << sa; 1778 break; 1779 case SRL: 1780 if (rs_reg == 0) { 1781 // Regular logical right shift of a word by a fixed number of 1782 // bits instruction. RS field is always equal to 0. 1783 *alu_out = rt_u >> sa; 1784 } else { 1785 // Logical right-rotate of a word by a fixed number of bits. This 1786 // is special case of SRL instruction, added in MIPS32 Release 2. 1787 // RS field is equal to 00001. 1788 *alu_out = (rt_u >> sa) | (rt_u << (32 - sa)); 1789 } 1790 break; 1791 case SRA: 1792 *alu_out = rt >> sa; 1793 break; 1794 case SLLV: 1795 *alu_out = rt << rs; 1796 break; 1797 case SRLV: 1798 if (sa == 0) { 1799 // Regular logical right-shift of a word by a variable number of 1800 // bits instruction. SA field is always equal to 0. 1801 *alu_out = rt_u >> rs; 1802 } else { 1803 // Logical right-rotate of a word by a variable number of bits. 1804 // This is special case od SRLV instruction, added in MIPS32 1805 // Release 2. SA field is equal to 00001. 1806 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u)); 1807 } 1808 break; 1809 case SRAV: 1810 *alu_out = rt >> rs; 1811 break; 1812 case MFHI: 1813 *alu_out = get_register(HI); 1814 break; 1815 case MFLO: 1816 *alu_out = get_register(LO); 1817 break; 1818 case MULT: 1819 *i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt); 1820 break; 1821 case MULTU: 1822 *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u); 1823 break; 1824 case ADD: 1825 if (HaveSameSign(rs, rt)) { 1826 if (rs > 0) { 1827 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); 1828 } else if (rs < 0) { 1829 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt); 1830 } 1831 } 1832 *alu_out = rs + rt; 1833 break; 1834 case ADDU: 1835 *alu_out = rs + rt; 1836 break; 1837 case SUB: 1838 if (!HaveSameSign(rs, rt)) { 1839 if (rs > 0) { 1840 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt); 1841 } else if (rs < 0) { 1842 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt); 1843 } 1844 } 1845 *alu_out = rs - rt; 1846 break; 1847 case SUBU: 1848 *alu_out = rs - rt; 1849 break; 1850 case AND: 1851 *alu_out = rs & rt; 1852 break; 1853 case OR: 1854 *alu_out = rs | rt; 1855 break; 1856 case XOR: 1857 *alu_out = rs ^ rt; 1858 break; 1859 case NOR: 1860 *alu_out = ~(rs | rt); 1861 break; 1862 case SLT: 1863 *alu_out = rs < rt ? 1 : 0; 1864 break; 1865 case SLTU: 1866 *alu_out = rs_u < rt_u ? 1 : 0; 1867 break; 1868 // Break and trap instructions. 1869 case BREAK: 1870 *do_interrupt = true; 1871 break; 1872 case TGE: 1873 *do_interrupt = rs >= rt; 1874 break; 1875 case TGEU: 1876 *do_interrupt = rs_u >= rt_u; 1877 break; 1878 case TLT: 1879 *do_interrupt = rs < rt; 1880 break; 1881 case TLTU: 1882 *do_interrupt = rs_u < rt_u; 1883 break; 1884 case TEQ: 1885 *do_interrupt = rs == rt; 1886 break; 1887 case TNE: 1888 *do_interrupt = rs != rt; 1889 break; 1890 case MOVN: 1891 case MOVZ: 1892 case MOVCI: 1893 // No action taken on decode. 1894 break; 1895 case DIV: 1896 case DIVU: 1897 // div and divu never raise exceptions. 1898 break; 1899 default: 1900 UNREACHABLE(); 1901 } 1902 break; 1903 case SPECIAL2: 1904 switch (instr->FunctionFieldRaw()) { 1905 case MUL: 1906 *alu_out = rs_u * rt_u; // Only the lower 32 bits are kept. 1907 break; 1908 case CLZ: 1909 // MIPS32 spec: If no bits were set in GPR rs, the result written to 1910 // GPR rd is 32. 1911 // GCC __builtin_clz: If input is 0, the result is undefined. 1912 *alu_out = 1913 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); 1914 break; 1915 default: 1916 UNREACHABLE(); 1917 } 1918 break; 1919 case SPECIAL3: 1920 switch (instr->FunctionFieldRaw()) { 1921 case INS: { // Mips32r2 instruction. 1922 // Interpret rd field as 5-bit msb of insert. 1923 uint16_t msb = rd_reg; 1924 // Interpret sa field as 5-bit lsb of insert. 1925 uint16_t lsb = sa; 1926 uint16_t size = msb - lsb + 1; 1927 uint32_t mask = (1 << size) - 1; 1928 *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb); 1929 break; 1930 } 1931 case EXT: { // Mips32r2 instruction. 1932 // Interpret rd field as 5-bit msb of extract. 1933 uint16_t msb = rd_reg; 1934 // Interpret sa field as 5-bit lsb of extract. 1935 uint16_t lsb = sa; 1936 uint16_t size = msb + 1; 1937 uint32_t mask = (1 << size) - 1; 1938 *alu_out = (rs_u & (mask << lsb)) >> lsb; 1939 break; 1940 } 1941 default: 1942 UNREACHABLE(); 1943 } 1944 break; 1945 default: 1946 UNREACHABLE(); 1947 } 1948 } 1949 1950 1951 void Simulator::DecodeTypeRegister(Instruction* instr) { 1952 // Instruction fields. 1953 const Opcode op = instr->OpcodeFieldRaw(); 1954 const int32_t rs_reg = instr->RsValue(); 1955 const int32_t rs = get_register(rs_reg); 1956 const uint32_t rs_u = static_cast<uint32_t>(rs); 1957 const int32_t rt_reg = instr->RtValue(); 1958 const int32_t rt = get_register(rt_reg); 1959 const uint32_t rt_u = static_cast<uint32_t>(rt); 1960 const int32_t rd_reg = instr->RdValue(); 1961 1962 const int32_t fr_reg = instr->FrValue(); 1963 const int32_t fs_reg = instr->FsValue(); 1964 const int32_t ft_reg = instr->FtValue(); 1965 const int32_t fd_reg = instr->FdValue(); 1966 int64_t i64hilo = 0; 1967 uint64_t u64hilo = 0; 1968 1969 // ALU output. 1970 // It should not be used as is. Instructions using it should always 1971 // initialize it first. 1972 int32_t alu_out = 0x12345678; 1973 1974 // For break and trap instructions. 1975 bool do_interrupt = false; 1976 1977 // For jr and jalr. 1978 // Get current pc. 1979 int32_t current_pc = get_pc(); 1980 // Next pc 1981 int32_t next_pc = 0; 1982 int32_t return_addr_reg = 31; 1983 1984 // Set up the variables if needed before executing the instruction. 1985 ConfigureTypeRegister(instr, 1986 &alu_out, 1987 &i64hilo, 1988 &u64hilo, 1989 &next_pc, 1990 &return_addr_reg, 1991 &do_interrupt); 1992 1993 // ---------- Raise exceptions triggered. 1994 SignalExceptions(); 1995 1996 // ---------- Execution. 1997 switch (op) { 1998 case COP1: 1999 switch (instr->RsFieldRaw()) { 2000 case BC1: // Branch on coprocessor condition. 2001 UNREACHABLE(); 2002 break; 2003 case CFC1: 2004 set_register(rt_reg, alu_out); 2005 case MFC1: 2006 set_register(rt_reg, alu_out); 2007 break; 2008 case MFHC1: 2009 UNIMPLEMENTED_MIPS(); 2010 break; 2011 case CTC1: 2012 // At the moment only FCSR is supported. 2013 ASSERT(fs_reg == kFCSRRegister); 2014 FCSR_ = registers_[rt_reg]; 2015 break; 2016 case MTC1: 2017 FPUregisters_[fs_reg] = registers_[rt_reg]; 2018 break; 2019 case MTHC1: 2020 UNIMPLEMENTED_MIPS(); 2021 break; 2022 case S: 2023 float f; 2024 switch (instr->FunctionFieldRaw()) { 2025 case CVT_D_S: 2026 f = get_fpu_register_float(fs_reg); 2027 set_fpu_register_double(fd_reg, static_cast<double>(f)); 2028 break; 2029 case CVT_W_S: 2030 case CVT_L_S: 2031 case TRUNC_W_S: 2032 case TRUNC_L_S: 2033 case ROUND_W_S: 2034 case ROUND_L_S: 2035 case FLOOR_W_S: 2036 case FLOOR_L_S: 2037 case CEIL_W_S: 2038 case CEIL_L_S: 2039 case CVT_PS_S: 2040 UNIMPLEMENTED_MIPS(); 2041 break; 2042 default: 2043 UNREACHABLE(); 2044 } 2045 break; 2046 case D: 2047 double ft, fs; 2048 uint32_t cc, fcsr_cc; 2049 int64_t i64; 2050 fs = get_fpu_register_double(fs_reg); 2051 ft = get_fpu_register_double(ft_reg); 2052 cc = instr->FCccValue(); 2053 fcsr_cc = get_fcsr_condition_bit(cc); 2054 switch (instr->FunctionFieldRaw()) { 2055 case ADD_D: 2056 set_fpu_register_double(fd_reg, fs + ft); 2057 break; 2058 case SUB_D: 2059 set_fpu_register_double(fd_reg, fs - ft); 2060 break; 2061 case MUL_D: 2062 set_fpu_register_double(fd_reg, fs * ft); 2063 break; 2064 case DIV_D: 2065 set_fpu_register_double(fd_reg, fs / ft); 2066 break; 2067 case ABS_D: 2068 set_fpu_register_double(fd_reg, fabs(fs)); 2069 break; 2070 case MOV_D: 2071 set_fpu_register_double(fd_reg, fs); 2072 break; 2073 case NEG_D: 2074 set_fpu_register_double(fd_reg, -fs); 2075 break; 2076 case SQRT_D: 2077 set_fpu_register_double(fd_reg, sqrt(fs)); 2078 break; 2079 case C_UN_D: 2080 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2081 break; 2082 case C_EQ_D: 2083 set_fcsr_bit(fcsr_cc, (fs == ft)); 2084 break; 2085 case C_UEQ_D: 2086 set_fcsr_bit(fcsr_cc, 2087 (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2088 break; 2089 case C_OLT_D: 2090 set_fcsr_bit(fcsr_cc, (fs < ft)); 2091 break; 2092 case C_ULT_D: 2093 set_fcsr_bit(fcsr_cc, 2094 (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 2095 break; 2096 case C_OLE_D: 2097 set_fcsr_bit(fcsr_cc, (fs <= ft)); 2098 break; 2099 case C_ULE_D: 2100 set_fcsr_bit(fcsr_cc, 2101 (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2102 break; 2103 case CVT_W_D: // Convert double to word. 2104 // Rounding modes are not yet supported. 2105 ASSERT((FCSR_ & 3) == 0); 2106 // In rounding mode 0 it should behave like ROUND. 2107 case ROUND_W_D: // Round double to word (round half to even). 2108 { 2109 double rounded = std::floor(fs + 0.5); 2110 int32_t result = static_cast<int32_t>(rounded); 2111 if ((result & 1) != 0 && result - fs == 0.5) { 2112 // If the number is halfway between two integers, 2113 // round to the even one. 2114 result--; 2115 } 2116 set_fpu_register(fd_reg, result); 2117 if (set_fcsr_round_error(fs, rounded)) { 2118 set_fpu_register(fd_reg, kFPUInvalidResult); 2119 } 2120 } 2121 break; 2122 case TRUNC_W_D: // Truncate double to word (round towards 0). 2123 { 2124 double rounded = trunc(fs); 2125 int32_t result = static_cast<int32_t>(rounded); 2126 set_fpu_register(fd_reg, result); 2127 if (set_fcsr_round_error(fs, rounded)) { 2128 set_fpu_register(fd_reg, kFPUInvalidResult); 2129 } 2130 } 2131 break; 2132 case FLOOR_W_D: // Round double to word towards negative infinity. 2133 { 2134 double rounded = std::floor(fs); 2135 int32_t result = static_cast<int32_t>(rounded); 2136 set_fpu_register(fd_reg, result); 2137 if (set_fcsr_round_error(fs, rounded)) { 2138 set_fpu_register(fd_reg, kFPUInvalidResult); 2139 } 2140 } 2141 break; 2142 case CEIL_W_D: // Round double to word towards positive infinity. 2143 { 2144 double rounded = std::ceil(fs); 2145 int32_t result = static_cast<int32_t>(rounded); 2146 set_fpu_register(fd_reg, result); 2147 if (set_fcsr_round_error(fs, rounded)) { 2148 set_fpu_register(fd_reg, kFPUInvalidResult); 2149 } 2150 } 2151 break; 2152 case CVT_S_D: // Convert double to float (single). 2153 set_fpu_register_float(fd_reg, static_cast<float>(fs)); 2154 break; 2155 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. 2156 double rounded = trunc(fs); 2157 i64 = static_cast<int64_t>(rounded); 2158 set_fpu_register(fd_reg, i64 & 0xffffffff); 2159 set_fpu_register(fd_reg + 1, i64 >> 32); 2160 break; 2161 } 2162 case TRUNC_L_D: { // Mips32r2 instruction. 2163 double rounded = trunc(fs); 2164 i64 = static_cast<int64_t>(rounded); 2165 set_fpu_register(fd_reg, i64 & 0xffffffff); 2166 set_fpu_register(fd_reg + 1, i64 >> 32); 2167 break; 2168 } 2169 case ROUND_L_D: { // Mips32r2 instruction. 2170 double rounded = 2171 fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5); 2172 i64 = static_cast<int64_t>(rounded); 2173 set_fpu_register(fd_reg, i64 & 0xffffffff); 2174 set_fpu_register(fd_reg + 1, i64 >> 32); 2175 break; 2176 } 2177 case FLOOR_L_D: // Mips32r2 instruction. 2178 i64 = static_cast<int64_t>(std::floor(fs)); 2179 set_fpu_register(fd_reg, i64 & 0xffffffff); 2180 set_fpu_register(fd_reg + 1, i64 >> 32); 2181 break; 2182 case CEIL_L_D: // Mips32r2 instruction. 2183 i64 = static_cast<int64_t>(std::ceil(fs)); 2184 set_fpu_register(fd_reg, i64 & 0xffffffff); 2185 set_fpu_register(fd_reg + 1, i64 >> 32); 2186 break; 2187 case C_F_D: 2188 UNIMPLEMENTED_MIPS(); 2189 break; 2190 default: 2191 UNREACHABLE(); 2192 } 2193 break; 2194 case W: 2195 switch (instr->FunctionFieldRaw()) { 2196 case CVT_S_W: // Convert word to float (single). 2197 alu_out = get_fpu_register(fs_reg); 2198 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); 2199 break; 2200 case CVT_D_W: // Convert word to double. 2201 alu_out = get_fpu_register(fs_reg); 2202 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); 2203 break; 2204 default: 2205 UNREACHABLE(); 2206 } 2207 break; 2208 case L: 2209 switch (instr->FunctionFieldRaw()) { 2210 case CVT_D_L: // Mips32r2 instruction. 2211 // Watch the signs here, we want 2 32-bit vals 2212 // to make a sign-64. 2213 i64 = static_cast<uint32_t>(get_fpu_register(fs_reg)); 2214 i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32; 2215 set_fpu_register_double(fd_reg, static_cast<double>(i64)); 2216 break; 2217 case CVT_S_L: 2218 UNIMPLEMENTED_MIPS(); 2219 break; 2220 default: 2221 UNREACHABLE(); 2222 } 2223 break; 2224 case PS: 2225 break; 2226 default: 2227 UNREACHABLE(); 2228 } 2229 break; 2230 case COP1X: 2231 switch (instr->FunctionFieldRaw()) { 2232 case MADD_D: 2233 double fr, ft, fs; 2234 fr = get_fpu_register_double(fr_reg); 2235 fs = get_fpu_register_double(fs_reg); 2236 ft = get_fpu_register_double(ft_reg); 2237 set_fpu_register_double(fd_reg, fs * ft + fr); 2238 break; 2239 default: 2240 UNREACHABLE(); 2241 } 2242 break; 2243 case SPECIAL: 2244 switch (instr->FunctionFieldRaw()) { 2245 case JR: { 2246 Instruction* branch_delay_instr = reinterpret_cast<Instruction*>( 2247 current_pc+Instruction::kInstrSize); 2248 BranchDelayInstructionDecode(branch_delay_instr); 2249 set_pc(next_pc); 2250 pc_modified_ = true; 2251 break; 2252 } 2253 case JALR: { 2254 Instruction* branch_delay_instr = reinterpret_cast<Instruction*>( 2255 current_pc+Instruction::kInstrSize); 2256 BranchDelayInstructionDecode(branch_delay_instr); 2257 set_register(return_addr_reg, 2258 current_pc + 2 * Instruction::kInstrSize); 2259 set_pc(next_pc); 2260 pc_modified_ = true; 2261 break; 2262 } 2263 // Instructions using HI and LO registers. 2264 case MULT: 2265 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); 2266 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); 2267 break; 2268 case MULTU: 2269 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); 2270 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); 2271 break; 2272 case DIV: 2273 // Divide by zero and overflow was not checked in the configuration 2274 // step - div and divu do not raise exceptions. On division by 0 2275 // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1), 2276 // return INT_MIN which is what the hardware does. 2277 if (rs == INT_MIN && rt == -1) { 2278 set_register(LO, INT_MIN); 2279 set_register(HI, 0); 2280 } else if (rt != 0) { 2281 set_register(LO, rs / rt); 2282 set_register(HI, rs % rt); 2283 } 2284 break; 2285 case DIVU: 2286 if (rt_u != 0) { 2287 set_register(LO, rs_u / rt_u); 2288 set_register(HI, rs_u % rt_u); 2289 } 2290 break; 2291 // Break and trap instructions. 2292 case BREAK: 2293 case TGE: 2294 case TGEU: 2295 case TLT: 2296 case TLTU: 2297 case TEQ: 2298 case TNE: 2299 if (do_interrupt) { 2300 SoftwareInterrupt(instr); 2301 } 2302 break; 2303 // Conditional moves. 2304 case MOVN: 2305 if (rt) set_register(rd_reg, rs); 2306 break; 2307 case MOVCI: { 2308 uint32_t cc = instr->FBccValue(); 2309 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 2310 if (instr->Bit(16)) { // Read Tf bit. 2311 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs); 2312 } else { 2313 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs); 2314 } 2315 break; 2316 } 2317 case MOVZ: 2318 if (!rt) set_register(rd_reg, rs); 2319 break; 2320 default: // For other special opcodes we do the default operation. 2321 set_register(rd_reg, alu_out); 2322 } 2323 break; 2324 case SPECIAL2: 2325 switch (instr->FunctionFieldRaw()) { 2326 case MUL: 2327 set_register(rd_reg, alu_out); 2328 // HI and LO are UNPREDICTABLE after the operation. 2329 set_register(LO, Unpredictable); 2330 set_register(HI, Unpredictable); 2331 break; 2332 default: // For other special2 opcodes we do the default operation. 2333 set_register(rd_reg, alu_out); 2334 } 2335 break; 2336 case SPECIAL3: 2337 switch (instr->FunctionFieldRaw()) { 2338 case INS: 2339 // Ins instr leaves result in Rt, rather than Rd. 2340 set_register(rt_reg, alu_out); 2341 break; 2342 case EXT: 2343 // Ext instr leaves result in Rt, rather than Rd. 2344 set_register(rt_reg, alu_out); 2345 break; 2346 default: 2347 UNREACHABLE(); 2348 } 2349 break; 2350 // Unimplemented opcodes raised an error in the configuration step before, 2351 // so we can use the default here to set the destination register in common 2352 // cases. 2353 default: 2354 set_register(rd_reg, alu_out); 2355 } 2356 } 2357 2358 2359 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). 2360 void Simulator::DecodeTypeImmediate(Instruction* instr) { 2361 // Instruction fields. 2362 Opcode op = instr->OpcodeFieldRaw(); 2363 int32_t rs = get_register(instr->RsValue()); 2364 uint32_t rs_u = static_cast<uint32_t>(rs); 2365 int32_t rt_reg = instr->RtValue(); // Destination register. 2366 int32_t rt = get_register(rt_reg); 2367 int16_t imm16 = instr->Imm16Value(); 2368 2369 int32_t ft_reg = instr->FtValue(); // Destination register. 2370 2371 // Zero extended immediate. 2372 uint32_t oe_imm16 = 0xffff & imm16; 2373 // Sign extended immediate. 2374 int32_t se_imm16 = imm16; 2375 2376 // Get current pc. 2377 int32_t current_pc = get_pc(); 2378 // Next pc. 2379 int32_t next_pc = bad_ra; 2380 2381 // Used for conditional branch instructions. 2382 bool do_branch = false; 2383 bool execute_branch_delay_instruction = false; 2384 2385 // Used for arithmetic instructions. 2386 int32_t alu_out = 0; 2387 // Floating point. 2388 double fp_out = 0.0; 2389 uint32_t cc, cc_value, fcsr_cc; 2390 2391 // Used for memory instructions. 2392 int32_t addr = 0x0; 2393 // Value to be written in memory. 2394 uint32_t mem_value = 0x0; 2395 2396 // ---------- Configuration (and execution for REGIMM). 2397 switch (op) { 2398 // ------------- COP1. Coprocessor instructions. 2399 case COP1: 2400 switch (instr->RsFieldRaw()) { 2401 case BC1: // Branch on coprocessor condition. 2402 cc = instr->FBccValue(); 2403 fcsr_cc = get_fcsr_condition_bit(cc); 2404 cc_value = test_fcsr_bit(fcsr_cc); 2405 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; 2406 execute_branch_delay_instruction = true; 2407 // Set next_pc. 2408 if (do_branch) { 2409 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 2410 } else { 2411 next_pc = current_pc + kBranchReturnOffset; 2412 } 2413 break; 2414 default: 2415 UNREACHABLE(); 2416 } 2417 break; 2418 // ------------- REGIMM class. 2419 case REGIMM: 2420 switch (instr->RtFieldRaw()) { 2421 case BLTZ: 2422 do_branch = (rs < 0); 2423 break; 2424 case BLTZAL: 2425 do_branch = rs < 0; 2426 break; 2427 case BGEZ: 2428 do_branch = rs >= 0; 2429 break; 2430 case BGEZAL: 2431 do_branch = rs >= 0; 2432 break; 2433 default: 2434 UNREACHABLE(); 2435 } 2436 switch (instr->RtFieldRaw()) { 2437 case BLTZ: 2438 case BLTZAL: 2439 case BGEZ: 2440 case BGEZAL: 2441 // Branch instructions common part. 2442 execute_branch_delay_instruction = true; 2443 // Set next_pc. 2444 if (do_branch) { 2445 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 2446 if (instr->IsLinkingInstruction()) { 2447 set_register(31, current_pc + kBranchReturnOffset); 2448 } 2449 } else { 2450 next_pc = current_pc + kBranchReturnOffset; 2451 } 2452 default: 2453 break; 2454 } 2455 break; // case REGIMM. 2456 // ------------- Branch instructions. 2457 // When comparing to zero, the encoding of rt field is always 0, so we don't 2458 // need to replace rt with zero. 2459 case BEQ: 2460 do_branch = (rs == rt); 2461 break; 2462 case BNE: 2463 do_branch = rs != rt; 2464 break; 2465 case BLEZ: 2466 do_branch = rs <= 0; 2467 break; 2468 case BGTZ: 2469 do_branch = rs > 0; 2470 break; 2471 // ------------- Arithmetic instructions. 2472 case ADDI: 2473 if (HaveSameSign(rs, se_imm16)) { 2474 if (rs > 0) { 2475 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16); 2476 } else if (rs < 0) { 2477 exceptions[kIntegerUnderflow] = 2478 rs < (Registers::kMinValue - se_imm16); 2479 } 2480 } 2481 alu_out = rs + se_imm16; 2482 break; 2483 case ADDIU: 2484 alu_out = rs + se_imm16; 2485 break; 2486 case SLTI: 2487 alu_out = (rs < se_imm16) ? 1 : 0; 2488 break; 2489 case SLTIU: 2490 alu_out = (rs_u < static_cast<uint32_t>(se_imm16)) ? 1 : 0; 2491 break; 2492 case ANDI: 2493 alu_out = rs & oe_imm16; 2494 break; 2495 case ORI: 2496 alu_out = rs | oe_imm16; 2497 break; 2498 case XORI: 2499 alu_out = rs ^ oe_imm16; 2500 break; 2501 case LUI: 2502 alu_out = (oe_imm16 << 16); 2503 break; 2504 // ------------- Memory instructions. 2505 case LB: 2506 addr = rs + se_imm16; 2507 alu_out = ReadB(addr); 2508 break; 2509 case LH: 2510 addr = rs + se_imm16; 2511 alu_out = ReadH(addr, instr); 2512 break; 2513 case LWL: { 2514 // al_offset is offset of the effective address within an aligned word. 2515 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 2516 uint8_t byte_shift = kPointerAlignmentMask - al_offset; 2517 uint32_t mask = (1 << byte_shift * 8) - 1; 2518 addr = rs + se_imm16 - al_offset; 2519 alu_out = ReadW(addr, instr); 2520 alu_out <<= byte_shift * 8; 2521 alu_out |= rt & mask; 2522 break; 2523 } 2524 case LW: 2525 addr = rs + se_imm16; 2526 alu_out = ReadW(addr, instr); 2527 break; 2528 case LBU: 2529 addr = rs + se_imm16; 2530 alu_out = ReadBU(addr); 2531 break; 2532 case LHU: 2533 addr = rs + se_imm16; 2534 alu_out = ReadHU(addr, instr); 2535 break; 2536 case LWR: { 2537 // al_offset is offset of the effective address within an aligned word. 2538 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 2539 uint8_t byte_shift = kPointerAlignmentMask - al_offset; 2540 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; 2541 addr = rs + se_imm16 - al_offset; 2542 alu_out = ReadW(addr, instr); 2543 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; 2544 alu_out |= rt & mask; 2545 break; 2546 } 2547 case SB: 2548 addr = rs + se_imm16; 2549 break; 2550 case SH: 2551 addr = rs + se_imm16; 2552 break; 2553 case SWL: { 2554 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 2555 uint8_t byte_shift = kPointerAlignmentMask - al_offset; 2556 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; 2557 addr = rs + se_imm16 - al_offset; 2558 mem_value = ReadW(addr, instr) & mask; 2559 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8; 2560 break; 2561 } 2562 case SW: 2563 addr = rs + se_imm16; 2564 break; 2565 case SWR: { 2566 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 2567 uint32_t mask = (1 << al_offset * 8) - 1; 2568 addr = rs + se_imm16 - al_offset; 2569 mem_value = ReadW(addr, instr); 2570 mem_value = (rt << al_offset * 8) | (mem_value & mask); 2571 break; 2572 } 2573 case LWC1: 2574 addr = rs + se_imm16; 2575 alu_out = ReadW(addr, instr); 2576 break; 2577 case LDC1: 2578 addr = rs + se_imm16; 2579 fp_out = ReadD(addr, instr); 2580 break; 2581 case SWC1: 2582 case SDC1: 2583 addr = rs + se_imm16; 2584 break; 2585 default: 2586 UNREACHABLE(); 2587 } 2588 2589 // ---------- Raise exceptions triggered. 2590 SignalExceptions(); 2591 2592 // ---------- Execution. 2593 switch (op) { 2594 // ------------- Branch instructions. 2595 case BEQ: 2596 case BNE: 2597 case BLEZ: 2598 case BGTZ: 2599 // Branch instructions common part. 2600 execute_branch_delay_instruction = true; 2601 // Set next_pc. 2602 if (do_branch) { 2603 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 2604 if (instr->IsLinkingInstruction()) { 2605 set_register(31, current_pc + 2* Instruction::kInstrSize); 2606 } 2607 } else { 2608 next_pc = current_pc + 2 * Instruction::kInstrSize; 2609 } 2610 break; 2611 // ------------- Arithmetic instructions. 2612 case ADDI: 2613 case ADDIU: 2614 case SLTI: 2615 case SLTIU: 2616 case ANDI: 2617 case ORI: 2618 case XORI: 2619 case LUI: 2620 set_register(rt_reg, alu_out); 2621 break; 2622 // ------------- Memory instructions. 2623 case LB: 2624 case LH: 2625 case LWL: 2626 case LW: 2627 case LBU: 2628 case LHU: 2629 case LWR: 2630 set_register(rt_reg, alu_out); 2631 break; 2632 case SB: 2633 WriteB(addr, static_cast<int8_t>(rt)); 2634 break; 2635 case SH: 2636 WriteH(addr, static_cast<uint16_t>(rt), instr); 2637 break; 2638 case SWL: 2639 WriteW(addr, mem_value, instr); 2640 break; 2641 case SW: 2642 WriteW(addr, rt, instr); 2643 break; 2644 case SWR: 2645 WriteW(addr, mem_value, instr); 2646 break; 2647 case LWC1: 2648 set_fpu_register(ft_reg, alu_out); 2649 break; 2650 case LDC1: 2651 set_fpu_register_double(ft_reg, fp_out); 2652 break; 2653 case SWC1: 2654 addr = rs + se_imm16; 2655 WriteW(addr, get_fpu_register(ft_reg), instr); 2656 break; 2657 case SDC1: 2658 addr = rs + se_imm16; 2659 WriteD(addr, get_fpu_register_double(ft_reg), instr); 2660 break; 2661 default: 2662 break; 2663 } 2664 2665 2666 if (execute_branch_delay_instruction) { 2667 // Execute branch delay slot 2668 // We don't check for end_sim_pc. First it should not be met as the current 2669 // pc is valid. Secondly a jump should always execute its branch delay slot. 2670 Instruction* branch_delay_instr = 2671 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); 2672 BranchDelayInstructionDecode(branch_delay_instr); 2673 } 2674 2675 // If needed update pc after the branch delay execution. 2676 if (next_pc != bad_ra) { 2677 set_pc(next_pc); 2678 } 2679 } 2680 2681 2682 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). 2683 void Simulator::DecodeTypeJump(Instruction* instr) { 2684 // Get current pc. 2685 int32_t current_pc = get_pc(); 2686 // Get unchanged bits of pc. 2687 int32_t pc_high_bits = current_pc & 0xf0000000; 2688 // Next pc. 2689 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); 2690 2691 // Execute branch delay slot. 2692 // We don't check for end_sim_pc. First it should not be met as the current pc 2693 // is valid. Secondly a jump should always execute its branch delay slot. 2694 Instruction* branch_delay_instr = 2695 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); 2696 BranchDelayInstructionDecode(branch_delay_instr); 2697 2698 // Update pc and ra if necessary. 2699 // Do this after the branch delay execution. 2700 if (instr->IsLinkingInstruction()) { 2701 set_register(31, current_pc + 2 * Instruction::kInstrSize); 2702 } 2703 set_pc(next_pc); 2704 pc_modified_ = true; 2705 } 2706 2707 2708 // Executes the current instruction. 2709 void Simulator::InstructionDecode(Instruction* instr) { 2710 if (v8::internal::FLAG_check_icache) { 2711 CheckICache(isolate_->simulator_i_cache(), instr); 2712 } 2713 pc_modified_ = false; 2714 if (::v8::internal::FLAG_trace_sim) { 2715 disasm::NameConverter converter; 2716 disasm::Disassembler dasm(converter); 2717 // Use a reasonably large buffer. 2718 v8::internal::EmbeddedVector<char, 256> buffer; 2719 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); 2720 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), 2721 buffer.start()); 2722 } 2723 2724 switch (instr->InstructionType()) { 2725 case Instruction::kRegisterType: 2726 DecodeTypeRegister(instr); 2727 break; 2728 case Instruction::kImmediateType: 2729 DecodeTypeImmediate(instr); 2730 break; 2731 case Instruction::kJumpType: 2732 DecodeTypeJump(instr); 2733 break; 2734 default: 2735 UNSUPPORTED(); 2736 } 2737 if (!pc_modified_) { 2738 set_register(pc, reinterpret_cast<int32_t>(instr) + 2739 Instruction::kInstrSize); 2740 } 2741 } 2742 2743 2744 2745 void Simulator::Execute() { 2746 // Get the PC to simulate. Cannot use the accessor here as we need the 2747 // raw PC value and not the one used as input to arithmetic instructions. 2748 int program_counter = get_pc(); 2749 if (::v8::internal::FLAG_stop_sim_at == 0) { 2750 // Fast version of the dispatch loop without checking whether the simulator 2751 // should be stopping at a particular executed instruction. 2752 while (program_counter != end_sim_pc) { 2753 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 2754 icount_++; 2755 InstructionDecode(instr); 2756 program_counter = get_pc(); 2757 } 2758 } else { 2759 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 2760 // we reach the particular instuction count. 2761 while (program_counter != end_sim_pc) { 2762 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 2763 icount_++; 2764 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { 2765 MipsDebugger dbg(this); 2766 dbg.Debug(); 2767 } else { 2768 InstructionDecode(instr); 2769 } 2770 program_counter = get_pc(); 2771 } 2772 } 2773 } 2774 2775 2776 void Simulator::CallInternal(byte* entry) { 2777 // Prepare to execute the code at entry. 2778 set_register(pc, reinterpret_cast<int32_t>(entry)); 2779 // Put down marker for end of simulation. The simulator will stop simulation 2780 // when the PC reaches this value. By saving the "end simulation" value into 2781 // the LR the simulation stops when returning to this call point. 2782 set_register(ra, end_sim_pc); 2783 2784 // Remember the values of callee-saved registers. 2785 // The code below assumes that r9 is not used as sb (static base) in 2786 // simulator code and therefore is regarded as a callee-saved register. 2787 int32_t s0_val = get_register(s0); 2788 int32_t s1_val = get_register(s1); 2789 int32_t s2_val = get_register(s2); 2790 int32_t s3_val = get_register(s3); 2791 int32_t s4_val = get_register(s4); 2792 int32_t s5_val = get_register(s5); 2793 int32_t s6_val = get_register(s6); 2794 int32_t s7_val = get_register(s7); 2795 int32_t gp_val = get_register(gp); 2796 int32_t sp_val = get_register(sp); 2797 int32_t fp_val = get_register(fp); 2798 2799 // Set up the callee-saved registers with a known value. To be able to check 2800 // that they are preserved properly across JS execution. 2801 int32_t callee_saved_value = icount_; 2802 set_register(s0, callee_saved_value); 2803 set_register(s1, callee_saved_value); 2804 set_register(s2, callee_saved_value); 2805 set_register(s3, callee_saved_value); 2806 set_register(s4, callee_saved_value); 2807 set_register(s5, callee_saved_value); 2808 set_register(s6, callee_saved_value); 2809 set_register(s7, callee_saved_value); 2810 set_register(gp, callee_saved_value); 2811 set_register(fp, callee_saved_value); 2812 2813 // Start the simulation. 2814 Execute(); 2815 2816 // Check that the callee-saved registers have been preserved. 2817 CHECK_EQ(callee_saved_value, get_register(s0)); 2818 CHECK_EQ(callee_saved_value, get_register(s1)); 2819 CHECK_EQ(callee_saved_value, get_register(s2)); 2820 CHECK_EQ(callee_saved_value, get_register(s3)); 2821 CHECK_EQ(callee_saved_value, get_register(s4)); 2822 CHECK_EQ(callee_saved_value, get_register(s5)); 2823 CHECK_EQ(callee_saved_value, get_register(s6)); 2824 CHECK_EQ(callee_saved_value, get_register(s7)); 2825 CHECK_EQ(callee_saved_value, get_register(gp)); 2826 CHECK_EQ(callee_saved_value, get_register(fp)); 2827 2828 // Restore callee-saved registers with the original value. 2829 set_register(s0, s0_val); 2830 set_register(s1, s1_val); 2831 set_register(s2, s2_val); 2832 set_register(s3, s3_val); 2833 set_register(s4, s4_val); 2834 set_register(s5, s5_val); 2835 set_register(s6, s6_val); 2836 set_register(s7, s7_val); 2837 set_register(gp, gp_val); 2838 set_register(sp, sp_val); 2839 set_register(fp, fp_val); 2840 } 2841 2842 2843 int32_t Simulator::Call(byte* entry, int argument_count, ...) { 2844 va_list parameters; 2845 va_start(parameters, argument_count); 2846 // Set up arguments. 2847 2848 // First four arguments passed in registers. 2849 ASSERT(argument_count >= 4); 2850 set_register(a0, va_arg(parameters, int32_t)); 2851 set_register(a1, va_arg(parameters, int32_t)); 2852 set_register(a2, va_arg(parameters, int32_t)); 2853 set_register(a3, va_arg(parameters, int32_t)); 2854 2855 // Remaining arguments passed on stack. 2856 int original_stack = get_register(sp); 2857 // Compute position of stack on entry to generated code. 2858 int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) 2859 - kCArgsSlotsSize); 2860 if (OS::ActivationFrameAlignment() != 0) { 2861 entry_stack &= -OS::ActivationFrameAlignment(); 2862 } 2863 // Store remaining arguments on stack, from low to high memory. 2864 intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack); 2865 for (int i = 4; i < argument_count; i++) { 2866 stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t); 2867 } 2868 va_end(parameters); 2869 set_register(sp, entry_stack); 2870 2871 CallInternal(entry); 2872 2873 // Pop stack passed arguments. 2874 CHECK_EQ(entry_stack, get_register(sp)); 2875 set_register(sp, original_stack); 2876 2877 int32_t result = get_register(v0); 2878 return result; 2879 } 2880 2881 2882 double Simulator::CallFP(byte* entry, double d0, double d1) { 2883 if (!IsMipsSoftFloatABI) { 2884 set_fpu_register_double(f12, d0); 2885 set_fpu_register_double(f14, d1); 2886 } else { 2887 int buffer[2]; 2888 ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); 2889 memcpy(buffer, &d0, sizeof(d0)); 2890 set_dw_register(a0, buffer); 2891 memcpy(buffer, &d1, sizeof(d1)); 2892 set_dw_register(a2, buffer); 2893 } 2894 CallInternal(entry); 2895 if (!IsMipsSoftFloatABI) { 2896 return get_fpu_register_double(f0); 2897 } else { 2898 return get_double_from_register_pair(v0); 2899 } 2900 } 2901 2902 2903 uintptr_t Simulator::PushAddress(uintptr_t address) { 2904 int new_sp = get_register(sp) - sizeof(uintptr_t); 2905 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); 2906 *stack_slot = address; 2907 set_register(sp, new_sp); 2908 return new_sp; 2909 } 2910 2911 2912 uintptr_t Simulator::PopAddress() { 2913 int current_sp = get_register(sp); 2914 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 2915 uintptr_t address = *stack_slot; 2916 set_register(sp, current_sp + sizeof(uintptr_t)); 2917 return address; 2918 } 2919 2920 2921 #undef UNSUPPORTED 2922 2923 } } // namespace v8::internal 2924 2925 #endif // USE_SIMULATOR 2926 2927 #endif // V8_TARGET_ARCH_MIPS 2928