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