1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <stdlib.h> 6 #include <cmath> 7 #include <cstdarg> 8 #include "src/v8.h" 9 10 #if V8_TARGET_ARCH_ARM64 11 12 #include "src/arm64/decoder-arm64-inl.h" 13 #include "src/arm64/simulator-arm64.h" 14 #include "src/assembler.h" 15 #include "src/disasm.h" 16 #include "src/macro-assembler.h" 17 #include "src/ostreams.h" 18 19 namespace v8 { 20 namespace internal { 21 22 #if defined(USE_SIMULATOR) 23 24 25 // This macro provides a platform independent use of sscanf. The reason for 26 // SScanF not being implemented in a platform independent way through 27 // ::v8::internal::OS in the same way as SNPrintF is that the 28 // Windows C Run-Time Library does not provide vsscanf. 29 #define SScanF sscanf // NOLINT 30 31 32 // Helpers for colors. 33 #define COLOUR(colour_code) "\033[0;" colour_code "m" 34 #define COLOUR_BOLD(colour_code) "\033[1;" colour_code "m" 35 #define NORMAL "" 36 #define GREY "30" 37 #define RED "31" 38 #define GREEN "32" 39 #define YELLOW "33" 40 #define BLUE "34" 41 #define MAGENTA "35" 42 #define CYAN "36" 43 #define WHITE "37" 44 typedef char const * const TEXT_COLOUR; 45 TEXT_COLOUR clr_normal = FLAG_log_colour ? COLOUR(NORMAL) : ""; 46 TEXT_COLOUR clr_flag_name = FLAG_log_colour ? COLOUR_BOLD(WHITE) : ""; 47 TEXT_COLOUR clr_flag_value = FLAG_log_colour ? COLOUR(NORMAL) : ""; 48 TEXT_COLOUR clr_reg_name = FLAG_log_colour ? COLOUR_BOLD(CYAN) : ""; 49 TEXT_COLOUR clr_reg_value = FLAG_log_colour ? COLOUR(CYAN) : ""; 50 TEXT_COLOUR clr_fpreg_name = FLAG_log_colour ? COLOUR_BOLD(MAGENTA) : ""; 51 TEXT_COLOUR clr_fpreg_value = FLAG_log_colour ? COLOUR(MAGENTA) : ""; 52 TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR_BOLD(BLUE) : ""; 53 TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR_BOLD(YELLOW) : ""; 54 TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : ""; 55 TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : ""; 56 57 58 // This is basically the same as PrintF, with a guard for FLAG_trace_sim. 59 void Simulator::TraceSim(const char* format, ...) { 60 if (FLAG_trace_sim) { 61 va_list arguments; 62 va_start(arguments, format); 63 base::OS::VFPrint(stream_, format, arguments); 64 va_end(arguments); 65 } 66 } 67 68 69 const Instruction* Simulator::kEndOfSimAddress = NULL; 70 71 72 void SimSystemRegister::SetBits(int msb, int lsb, uint32_t bits) { 73 int width = msb - lsb + 1; 74 DCHECK(is_uintn(bits, width) || is_intn(bits, width)); 75 76 bits <<= lsb; 77 uint32_t mask = ((1 << width) - 1) << lsb; 78 DCHECK((mask & write_ignore_mask_) == 0); 79 80 value_ = (value_ & ~mask) | (bits & mask); 81 } 82 83 84 SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) { 85 switch (id) { 86 case NZCV: 87 return SimSystemRegister(0x00000000, NZCVWriteIgnoreMask); 88 case FPCR: 89 return SimSystemRegister(0x00000000, FPCRWriteIgnoreMask); 90 default: 91 UNREACHABLE(); 92 return SimSystemRegister(); 93 } 94 } 95 96 97 void Simulator::Initialize(Isolate* isolate) { 98 if (isolate->simulator_initialized()) return; 99 isolate->set_simulator_initialized(true); 100 ExternalReference::set_redirector(isolate, &RedirectExternalReference); 101 } 102 103 104 // Get the active Simulator for the current thread. 105 Simulator* Simulator::current(Isolate* isolate) { 106 Isolate::PerIsolateThreadData* isolate_data = 107 isolate->FindOrAllocatePerThreadDataForThisThread(); 108 DCHECK(isolate_data != NULL); 109 110 Simulator* sim = isolate_data->simulator(); 111 if (sim == NULL) { 112 if (FLAG_trace_sim || FLAG_log_instruction_stats || FLAG_debug_sim) { 113 sim = new Simulator(new Decoder<DispatchingDecoderVisitor>(), isolate); 114 } else { 115 sim = new Decoder<Simulator>(); 116 sim->isolate_ = isolate; 117 } 118 isolate_data->set_simulator(sim); 119 } 120 return sim; 121 } 122 123 124 void Simulator::CallVoid(byte* entry, CallArgument* args) { 125 int index_x = 0; 126 int index_d = 0; 127 128 std::vector<int64_t> stack_args(0); 129 for (int i = 0; !args[i].IsEnd(); i++) { 130 CallArgument arg = args[i]; 131 if (arg.IsX() && (index_x < 8)) { 132 set_xreg(index_x++, arg.bits()); 133 } else if (arg.IsD() && (index_d < 8)) { 134 set_dreg_bits(index_d++, arg.bits()); 135 } else { 136 DCHECK(arg.IsD() || arg.IsX()); 137 stack_args.push_back(arg.bits()); 138 } 139 } 140 141 // Process stack arguments, and make sure the stack is suitably aligned. 142 uintptr_t original_stack = sp(); 143 uintptr_t entry_stack = original_stack - 144 stack_args.size() * sizeof(stack_args[0]); 145 if (base::OS::ActivationFrameAlignment() != 0) { 146 entry_stack &= -base::OS::ActivationFrameAlignment(); 147 } 148 char * stack = reinterpret_cast<char*>(entry_stack); 149 std::vector<int64_t>::const_iterator it; 150 for (it = stack_args.begin(); it != stack_args.end(); it++) { 151 memcpy(stack, &(*it), sizeof(*it)); 152 stack += sizeof(*it); 153 } 154 155 DCHECK(reinterpret_cast<uintptr_t>(stack) <= original_stack); 156 set_sp(entry_stack); 157 158 // Call the generated code. 159 set_pc(entry); 160 set_lr(kEndOfSimAddress); 161 CheckPCSComplianceAndRun(); 162 163 set_sp(original_stack); 164 } 165 166 167 int64_t Simulator::CallInt64(byte* entry, CallArgument* args) { 168 CallVoid(entry, args); 169 return xreg(0); 170 } 171 172 173 double Simulator::CallDouble(byte* entry, CallArgument* args) { 174 CallVoid(entry, args); 175 return dreg(0); 176 } 177 178 179 int64_t Simulator::CallJS(byte* entry, 180 byte* function_entry, 181 JSFunction* func, 182 Object* revc, 183 int64_t argc, 184 Object*** argv) { 185 CallArgument args[] = { 186 CallArgument(function_entry), 187 CallArgument(func), 188 CallArgument(revc), 189 CallArgument(argc), 190 CallArgument(argv), 191 CallArgument::End() 192 }; 193 return CallInt64(entry, args); 194 } 195 196 int64_t Simulator::CallRegExp(byte* entry, 197 String* input, 198 int64_t start_offset, 199 const byte* input_start, 200 const byte* input_end, 201 int* output, 202 int64_t output_size, 203 Address stack_base, 204 int64_t direct_call, 205 void* return_address, 206 Isolate* isolate) { 207 CallArgument args[] = { 208 CallArgument(input), 209 CallArgument(start_offset), 210 CallArgument(input_start), 211 CallArgument(input_end), 212 CallArgument(output), 213 CallArgument(output_size), 214 CallArgument(stack_base), 215 CallArgument(direct_call), 216 CallArgument(return_address), 217 CallArgument(isolate), 218 CallArgument::End() 219 }; 220 return CallInt64(entry, args); 221 } 222 223 224 void Simulator::CheckPCSComplianceAndRun() { 225 #ifdef DEBUG 226 CHECK_EQ(kNumberOfCalleeSavedRegisters, kCalleeSaved.Count()); 227 CHECK_EQ(kNumberOfCalleeSavedFPRegisters, kCalleeSavedFP.Count()); 228 229 int64_t saved_registers[kNumberOfCalleeSavedRegisters]; 230 uint64_t saved_fpregisters[kNumberOfCalleeSavedFPRegisters]; 231 232 CPURegList register_list = kCalleeSaved; 233 CPURegList fpregister_list = kCalleeSavedFP; 234 235 for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) { 236 // x31 is not a caller saved register, so no need to specify if we want 237 // the stack or zero. 238 saved_registers[i] = xreg(register_list.PopLowestIndex().code()); 239 } 240 for (int i = 0; i < kNumberOfCalleeSavedFPRegisters; i++) { 241 saved_fpregisters[i] = 242 dreg_bits(fpregister_list.PopLowestIndex().code()); 243 } 244 int64_t original_stack = sp(); 245 #endif 246 // Start the simulation! 247 Run(); 248 #ifdef DEBUG 249 CHECK_EQ(original_stack, sp()); 250 // Check that callee-saved registers have been preserved. 251 register_list = kCalleeSaved; 252 fpregister_list = kCalleeSavedFP; 253 for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) { 254 CHECK_EQ(saved_registers[i], xreg(register_list.PopLowestIndex().code())); 255 } 256 for (int i = 0; i < kNumberOfCalleeSavedFPRegisters; i++) { 257 DCHECK(saved_fpregisters[i] == 258 dreg_bits(fpregister_list.PopLowestIndex().code())); 259 } 260 261 // Corrupt caller saved register minus the return regiters. 262 263 // In theory x0 to x7 can be used for return values, but V8 only uses x0, x1 264 // for now . 265 register_list = kCallerSaved; 266 register_list.Remove(x0); 267 register_list.Remove(x1); 268 269 // In theory d0 to d7 can be used for return values, but V8 only uses d0 270 // for now . 271 fpregister_list = kCallerSavedFP; 272 fpregister_list.Remove(d0); 273 274 CorruptRegisters(®ister_list, kCallerSavedRegisterCorruptionValue); 275 CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue); 276 #endif 277 } 278 279 280 #ifdef DEBUG 281 // The least significant byte of the curruption value holds the corresponding 282 // register's code. 283 void Simulator::CorruptRegisters(CPURegList* list, uint64_t value) { 284 if (list->type() == CPURegister::kRegister) { 285 while (!list->IsEmpty()) { 286 unsigned code = list->PopLowestIndex().code(); 287 set_xreg(code, value | code); 288 } 289 } else { 290 DCHECK(list->type() == CPURegister::kFPRegister); 291 while (!list->IsEmpty()) { 292 unsigned code = list->PopLowestIndex().code(); 293 set_dreg_bits(code, value | code); 294 } 295 } 296 } 297 298 299 void Simulator::CorruptAllCallerSavedCPURegisters() { 300 // Corrupt alters its parameter so copy them first. 301 CPURegList register_list = kCallerSaved; 302 CPURegList fpregister_list = kCallerSavedFP; 303 304 CorruptRegisters(®ister_list, kCallerSavedRegisterCorruptionValue); 305 CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue); 306 } 307 #endif 308 309 310 // Extending the stack by 2 * 64 bits is required for stack alignment purposes. 311 uintptr_t Simulator::PushAddress(uintptr_t address) { 312 DCHECK(sizeof(uintptr_t) < 2 * kXRegSize); 313 intptr_t new_sp = sp() - 2 * kXRegSize; 314 uintptr_t* alignment_slot = 315 reinterpret_cast<uintptr_t*>(new_sp + kXRegSize); 316 memcpy(alignment_slot, &kSlotsZapValue, kPointerSize); 317 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); 318 memcpy(stack_slot, &address, kPointerSize); 319 set_sp(new_sp); 320 return new_sp; 321 } 322 323 324 uintptr_t Simulator::PopAddress() { 325 intptr_t current_sp = sp(); 326 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 327 uintptr_t address = *stack_slot; 328 DCHECK(sizeof(uintptr_t) < 2 * kXRegSize); 329 set_sp(current_sp + 2 * kXRegSize); 330 return address; 331 } 332 333 334 // Returns the limit of the stack area to enable checking for stack overflows. 335 uintptr_t Simulator::StackLimit() const { 336 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when 337 // pushing values. 338 return stack_limit_ + 1024; 339 } 340 341 342 Simulator::Simulator(Decoder<DispatchingDecoderVisitor>* decoder, 343 Isolate* isolate, FILE* stream) 344 : decoder_(decoder), 345 last_debugger_input_(NULL), 346 log_parameters_(NO_PARAM), 347 isolate_(isolate) { 348 // Setup the decoder. 349 decoder_->AppendVisitor(this); 350 351 Init(stream); 352 353 if (FLAG_trace_sim) { 354 decoder_->InsertVisitorBefore(print_disasm_, this); 355 log_parameters_ = LOG_ALL; 356 } 357 358 if (FLAG_log_instruction_stats) { 359 instrument_ = new Instrument(FLAG_log_instruction_file, 360 FLAG_log_instruction_period); 361 decoder_->AppendVisitor(instrument_); 362 } 363 } 364 365 366 Simulator::Simulator() 367 : decoder_(NULL), 368 last_debugger_input_(NULL), 369 log_parameters_(NO_PARAM), 370 isolate_(NULL) { 371 Init(stdout); 372 CHECK(!FLAG_trace_sim && !FLAG_log_instruction_stats); 373 } 374 375 376 void Simulator::Init(FILE* stream) { 377 ResetState(); 378 379 // Allocate and setup the simulator stack. 380 stack_size_ = (FLAG_sim_stack_size * KB) + (2 * stack_protection_size_); 381 stack_ = reinterpret_cast<uintptr_t>(new byte[stack_size_]); 382 stack_limit_ = stack_ + stack_protection_size_; 383 uintptr_t tos = stack_ + stack_size_ - stack_protection_size_; 384 // The stack pointer must be 16-byte aligned. 385 set_sp(tos & ~0xfUL); 386 387 stream_ = stream; 388 print_disasm_ = new PrintDisassembler(stream_); 389 390 // The debugger needs to disassemble code without the simulator executing an 391 // instruction, so we create a dedicated decoder. 392 disassembler_decoder_ = new Decoder<DispatchingDecoderVisitor>(); 393 disassembler_decoder_->AppendVisitor(print_disasm_); 394 } 395 396 397 void Simulator::ResetState() { 398 // Reset the system registers. 399 nzcv_ = SimSystemRegister::DefaultValueFor(NZCV); 400 fpcr_ = SimSystemRegister::DefaultValueFor(FPCR); 401 402 // Reset registers to 0. 403 pc_ = NULL; 404 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 405 set_xreg(i, 0xbadbeef); 406 } 407 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 408 // Set FP registers to a value that is NaN in both 32-bit and 64-bit FP. 409 set_dreg_bits(i, 0x7ff000007f800001UL); 410 } 411 // Returning to address 0 exits the Simulator. 412 set_lr(kEndOfSimAddress); 413 414 // Reset debug helpers. 415 breakpoints_.empty(); 416 break_on_next_= false; 417 } 418 419 420 Simulator::~Simulator() { 421 delete[] reinterpret_cast<byte*>(stack_); 422 if (FLAG_log_instruction_stats) { 423 delete instrument_; 424 } 425 delete disassembler_decoder_; 426 delete print_disasm_; 427 DeleteArray(last_debugger_input_); 428 delete decoder_; 429 } 430 431 432 void Simulator::Run() { 433 pc_modified_ = false; 434 while (pc_ != kEndOfSimAddress) { 435 ExecuteInstruction(); 436 } 437 } 438 439 440 void Simulator::RunFrom(Instruction* start) { 441 set_pc(start); 442 Run(); 443 } 444 445 446 // When the generated code calls an external reference we need to catch that in 447 // the simulator. The external reference will be a function compiled for the 448 // host architecture. We need to call that function instead of trying to 449 // execute it with the simulator. We do that by redirecting the external 450 // reference to a svc (Supervisor Call) instruction that is handled by 451 // the simulator. We write the original destination of the jump just at a known 452 // offset from the svc instruction so the simulator knows what to call. 453 class Redirection { 454 public: 455 Redirection(void* external_function, ExternalReference::Type type) 456 : external_function_(external_function), 457 type_(type), 458 next_(NULL) { 459 redirect_call_.SetInstructionBits( 460 HLT | Assembler::ImmException(kImmExceptionIsRedirectedCall)); 461 Isolate* isolate = Isolate::Current(); 462 next_ = isolate->simulator_redirection(); 463 // TODO(all): Simulator flush I cache 464 isolate->set_simulator_redirection(this); 465 } 466 467 void* address_of_redirect_call() { 468 return reinterpret_cast<void*>(&redirect_call_); 469 } 470 471 template <typename T> 472 T external_function() { return reinterpret_cast<T>(external_function_); } 473 474 ExternalReference::Type type() { return type_; } 475 476 static Redirection* Get(void* external_function, 477 ExternalReference::Type type) { 478 Isolate* isolate = Isolate::Current(); 479 Redirection* current = isolate->simulator_redirection(); 480 for (; current != NULL; current = current->next_) { 481 if (current->external_function_ == external_function) { 482 DCHECK_EQ(current->type(), type); 483 return current; 484 } 485 } 486 return new Redirection(external_function, type); 487 } 488 489 static Redirection* FromHltInstruction(Instruction* redirect_call) { 490 char* addr_of_hlt = reinterpret_cast<char*>(redirect_call); 491 char* addr_of_redirection = 492 addr_of_hlt - OFFSET_OF(Redirection, redirect_call_); 493 return reinterpret_cast<Redirection*>(addr_of_redirection); 494 } 495 496 static void* ReverseRedirection(int64_t reg) { 497 Redirection* redirection = 498 FromHltInstruction(reinterpret_cast<Instruction*>(reg)); 499 return redirection->external_function<void*>(); 500 } 501 502 private: 503 void* external_function_; 504 Instruction redirect_call_; 505 ExternalReference::Type type_; 506 Redirection* next_; 507 }; 508 509 510 // Calls into the V8 runtime are based on this very simple interface. 511 // Note: To be able to return two values from some calls the code in runtime.cc 512 // uses the ObjectPair structure. 513 // The simulator assumes all runtime calls return two 64-bits values. If they 514 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. 515 struct ObjectPair { 516 int64_t res0; 517 int64_t res1; 518 }; 519 520 521 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, 522 int64_t arg1, 523 int64_t arg2, 524 int64_t arg3, 525 int64_t arg4, 526 int64_t arg5, 527 int64_t arg6, 528 int64_t arg7); 529 530 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); 531 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); 532 typedef double (*SimulatorRuntimeFPCall)(double arg1); 533 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); 534 535 // This signature supports direct call in to API function native callback 536 // (refer to InvocationCallback in v8.h). 537 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0); 538 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1); 539 540 // This signature supports direct call to accessor getter callback. 541 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1); 542 typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1, 543 void* arg2); 544 545 void Simulator::DoRuntimeCall(Instruction* instr) { 546 Redirection* redirection = Redirection::FromHltInstruction(instr); 547 548 // The called C code might itself call simulated code, so any 549 // caller-saved registers (including lr) could still be clobbered by a 550 // redirected call. 551 Instruction* return_address = lr(); 552 553 int64_t external = redirection->external_function<int64_t>(); 554 555 TraceSim("Call to host function at %p\n", 556 redirection->external_function<void*>()); 557 558 // SP must be 16-byte-aligned at the call interface. 559 bool stack_alignment_exception = ((sp() & 0xf) != 0); 560 if (stack_alignment_exception) { 561 TraceSim(" with unaligned stack 0x%016" PRIx64 ".\n", sp()); 562 FATAL("ALIGNMENT EXCEPTION"); 563 } 564 565 switch (redirection->type()) { 566 default: 567 TraceSim("Type: Unknown.\n"); 568 UNREACHABLE(); 569 break; 570 571 case ExternalReference::BUILTIN_CALL: { 572 // Object* f(v8::internal::Arguments). 573 TraceSim("Type: BUILTIN_CALL\n"); 574 SimulatorRuntimeCall target = 575 reinterpret_cast<SimulatorRuntimeCall>(external); 576 577 // We don't know how many arguments are being passed, but we can 578 // pass 8 without touching the stack. They will be ignored by the 579 // host function if they aren't used. 580 TraceSim("Arguments: " 581 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " 582 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " 583 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " 584 "0x%016" PRIx64 ", 0x%016" PRIx64, 585 xreg(0), xreg(1), xreg(2), xreg(3), 586 xreg(4), xreg(5), xreg(6), xreg(7)); 587 ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3), 588 xreg(4), xreg(5), xreg(6), xreg(7)); 589 TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64 "}\n", 590 result.res0, result.res1); 591 #ifdef DEBUG 592 CorruptAllCallerSavedCPURegisters(); 593 #endif 594 set_xreg(0, result.res0); 595 set_xreg(1, result.res1); 596 break; 597 } 598 599 case ExternalReference::DIRECT_API_CALL: { 600 // void f(v8::FunctionCallbackInfo&) 601 TraceSim("Type: DIRECT_API_CALL\n"); 602 SimulatorRuntimeDirectApiCall target = 603 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 604 TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0)); 605 target(xreg(0)); 606 TraceSim("No return value."); 607 #ifdef DEBUG 608 CorruptAllCallerSavedCPURegisters(); 609 #endif 610 break; 611 } 612 613 case ExternalReference::BUILTIN_COMPARE_CALL: { 614 // int f(double, double) 615 TraceSim("Type: BUILTIN_COMPARE_CALL\n"); 616 SimulatorRuntimeCompareCall target = 617 reinterpret_cast<SimulatorRuntimeCompareCall>(external); 618 TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1)); 619 int64_t result = target(dreg(0), dreg(1)); 620 TraceSim("Returned: %" PRId64 "\n", result); 621 #ifdef DEBUG 622 CorruptAllCallerSavedCPURegisters(); 623 #endif 624 set_xreg(0, result); 625 break; 626 } 627 628 case ExternalReference::BUILTIN_FP_CALL: { 629 // double f(double) 630 TraceSim("Type: BUILTIN_FP_CALL\n"); 631 SimulatorRuntimeFPCall target = 632 reinterpret_cast<SimulatorRuntimeFPCall>(external); 633 TraceSim("Argument: %f\n", dreg(0)); 634 double result = target(dreg(0)); 635 TraceSim("Returned: %f\n", result); 636 #ifdef DEBUG 637 CorruptAllCallerSavedCPURegisters(); 638 #endif 639 set_dreg(0, result); 640 break; 641 } 642 643 case ExternalReference::BUILTIN_FP_FP_CALL: { 644 // double f(double, double) 645 TraceSim("Type: BUILTIN_FP_FP_CALL\n"); 646 SimulatorRuntimeFPFPCall target = 647 reinterpret_cast<SimulatorRuntimeFPFPCall>(external); 648 TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1)); 649 double result = target(dreg(0), dreg(1)); 650 TraceSim("Returned: %f\n", result); 651 #ifdef DEBUG 652 CorruptAllCallerSavedCPURegisters(); 653 #endif 654 set_dreg(0, result); 655 break; 656 } 657 658 case ExternalReference::BUILTIN_FP_INT_CALL: { 659 // double f(double, int) 660 TraceSim("Type: BUILTIN_FP_INT_CALL\n"); 661 SimulatorRuntimeFPIntCall target = 662 reinterpret_cast<SimulatorRuntimeFPIntCall>(external); 663 TraceSim("Arguments: %f, %d\n", dreg(0), wreg(0)); 664 double result = target(dreg(0), wreg(0)); 665 TraceSim("Returned: %f\n", result); 666 #ifdef DEBUG 667 CorruptAllCallerSavedCPURegisters(); 668 #endif 669 set_dreg(0, result); 670 break; 671 } 672 673 case ExternalReference::DIRECT_GETTER_CALL: { 674 // void f(Local<String> property, PropertyCallbackInfo& info) 675 TraceSim("Type: DIRECT_GETTER_CALL\n"); 676 SimulatorRuntimeDirectGetterCall target = 677 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); 678 TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n", 679 xreg(0), xreg(1)); 680 target(xreg(0), xreg(1)); 681 TraceSim("No return value."); 682 #ifdef DEBUG 683 CorruptAllCallerSavedCPURegisters(); 684 #endif 685 break; 686 } 687 688 case ExternalReference::PROFILING_API_CALL: { 689 // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback) 690 TraceSim("Type: PROFILING_API_CALL\n"); 691 SimulatorRuntimeProfilingApiCall target = 692 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); 693 void* arg1 = Redirection::ReverseRedirection(xreg(1)); 694 TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1); 695 target(xreg(0), arg1); 696 TraceSim("No return value."); 697 #ifdef DEBUG 698 CorruptAllCallerSavedCPURegisters(); 699 #endif 700 break; 701 } 702 703 case ExternalReference::PROFILING_GETTER_CALL: { 704 // void f(Local<String> property, PropertyCallbackInfo& info, 705 // AccessorNameGetterCallback callback) 706 TraceSim("Type: PROFILING_GETTER_CALL\n"); 707 SimulatorRuntimeProfilingGetterCall target = 708 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>( 709 external); 710 void* arg2 = Redirection::ReverseRedirection(xreg(2)); 711 TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n", 712 xreg(0), xreg(1), arg2); 713 target(xreg(0), xreg(1), arg2); 714 TraceSim("No return value."); 715 #ifdef DEBUG 716 CorruptAllCallerSavedCPURegisters(); 717 #endif 718 break; 719 } 720 } 721 722 set_lr(return_address); 723 set_pc(return_address); 724 } 725 726 727 void* Simulator::RedirectExternalReference(void* external_function, 728 ExternalReference::Type type) { 729 Redirection* redirection = Redirection::Get(external_function, type); 730 return redirection->address_of_redirect_call(); 731 } 732 733 734 const char* Simulator::xreg_names[] = { 735 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", 736 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", 737 "ip0", "ip1", "x18", "x19", "x20", "x21", "x22", "x23", 738 "x24", "x25", "x26", "cp", "jssp", "fp", "lr", "xzr", "csp"}; 739 740 const char* Simulator::wreg_names[] = { 741 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", 742 "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", 743 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", 744 "w24", "w25", "w26", "wcp", "wjssp", "wfp", "wlr", "wzr", "wcsp"}; 745 746 const char* Simulator::sreg_names[] = { 747 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 748 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", 749 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", 750 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"}; 751 752 const char* Simulator::dreg_names[] = { 753 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 754 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", 755 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", 756 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"}; 757 758 const char* Simulator::vreg_names[] = { 759 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 760 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 761 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 762 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"}; 763 764 765 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) { 766 STATIC_ASSERT(arraysize(Simulator::wreg_names) == (kNumberOfRegisters + 1)); 767 DCHECK(code < kNumberOfRegisters); 768 // The modulo operator has no effect here, but it silences a broken GCC 769 // warning about out-of-bounds array accesses. 770 code %= kNumberOfRegisters; 771 772 // If the code represents the stack pointer, index the name after zr. 773 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 774 code = kZeroRegCode + 1; 775 } 776 return wreg_names[code]; 777 } 778 779 780 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) { 781 STATIC_ASSERT(arraysize(Simulator::xreg_names) == (kNumberOfRegisters + 1)); 782 DCHECK(code < kNumberOfRegisters); 783 code %= kNumberOfRegisters; 784 785 // If the code represents the stack pointer, index the name after zr. 786 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 787 code = kZeroRegCode + 1; 788 } 789 return xreg_names[code]; 790 } 791 792 793 const char* Simulator::SRegNameForCode(unsigned code) { 794 STATIC_ASSERT(arraysize(Simulator::sreg_names) == kNumberOfFPRegisters); 795 DCHECK(code < kNumberOfFPRegisters); 796 return sreg_names[code % kNumberOfFPRegisters]; 797 } 798 799 800 const char* Simulator::DRegNameForCode(unsigned code) { 801 STATIC_ASSERT(arraysize(Simulator::dreg_names) == kNumberOfFPRegisters); 802 DCHECK(code < kNumberOfFPRegisters); 803 return dreg_names[code % kNumberOfFPRegisters]; 804 } 805 806 807 const char* Simulator::VRegNameForCode(unsigned code) { 808 STATIC_ASSERT(arraysize(Simulator::vreg_names) == kNumberOfFPRegisters); 809 DCHECK(code < kNumberOfFPRegisters); 810 return vreg_names[code % kNumberOfFPRegisters]; 811 } 812 813 814 int Simulator::CodeFromName(const char* name) { 815 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 816 if ((strcmp(xreg_names[i], name) == 0) || 817 (strcmp(wreg_names[i], name) == 0)) { 818 return i; 819 } 820 } 821 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 822 if ((strcmp(vreg_names[i], name) == 0) || 823 (strcmp(dreg_names[i], name) == 0) || 824 (strcmp(sreg_names[i], name) == 0)) { 825 return i; 826 } 827 } 828 if ((strcmp("csp", name) == 0) || (strcmp("wcsp", name) == 0)) { 829 return kSPRegInternalCode; 830 } 831 return -1; 832 } 833 834 835 // Helpers --------------------------------------------------------------------- 836 template <typename T> 837 T Simulator::AddWithCarry(bool set_flags, 838 T src1, 839 T src2, 840 T carry_in) { 841 typedef typename make_unsigned<T>::type unsignedT; 842 DCHECK((carry_in == 0) || (carry_in == 1)); 843 844 T signed_sum = src1 + src2 + carry_in; 845 T result = signed_sum; 846 847 bool N, Z, C, V; 848 849 // Compute the C flag 850 unsignedT u1 = static_cast<unsignedT>(src1); 851 unsignedT u2 = static_cast<unsignedT>(src2); 852 unsignedT urest = std::numeric_limits<unsignedT>::max() - u1; 853 C = (u2 > urest) || (carry_in && (((u2 + 1) > urest) || (u2 > (urest - 1)))); 854 855 // Overflow iff the sign bit is the same for the two inputs and different 856 // for the result. 857 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0); 858 859 N = CalcNFlag(result); 860 Z = CalcZFlag(result); 861 862 if (set_flags) { 863 nzcv().SetN(N); 864 nzcv().SetZ(Z); 865 nzcv().SetC(C); 866 nzcv().SetV(V); 867 LogSystemRegister(NZCV); 868 } 869 return result; 870 } 871 872 873 template<typename T> 874 void Simulator::AddSubWithCarry(Instruction* instr) { 875 T op2 = reg<T>(instr->Rm()); 876 T new_val; 877 878 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) { 879 op2 = ~op2; 880 } 881 882 new_val = AddWithCarry<T>(instr->FlagsUpdate(), 883 reg<T>(instr->Rn()), 884 op2, 885 nzcv().C()); 886 887 set_reg<T>(instr->Rd(), new_val); 888 } 889 890 template <typename T> 891 T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) { 892 typedef typename make_unsigned<T>::type unsignedT; 893 894 if (amount == 0) { 895 return value; 896 } 897 898 switch (shift_type) { 899 case LSL: 900 return value << amount; 901 case LSR: 902 return static_cast<unsignedT>(value) >> amount; 903 case ASR: 904 return value >> amount; 905 case ROR: 906 return (static_cast<unsignedT>(value) >> amount) | 907 ((value & ((1L << amount) - 1L)) << 908 (sizeof(unsignedT) * 8 - amount)); 909 default: 910 UNIMPLEMENTED(); 911 return 0; 912 } 913 } 914 915 916 template <typename T> 917 T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) { 918 const unsigned kSignExtendBShift = (sizeof(T) - 1) * 8; 919 const unsigned kSignExtendHShift = (sizeof(T) - 2) * 8; 920 const unsigned kSignExtendWShift = (sizeof(T) - 4) * 8; 921 922 switch (extend_type) { 923 case UXTB: 924 value &= kByteMask; 925 break; 926 case UXTH: 927 value &= kHalfWordMask; 928 break; 929 case UXTW: 930 value &= kWordMask; 931 break; 932 case SXTB: 933 value = (value << kSignExtendBShift) >> kSignExtendBShift; 934 break; 935 case SXTH: 936 value = (value << kSignExtendHShift) >> kSignExtendHShift; 937 break; 938 case SXTW: 939 value = (value << kSignExtendWShift) >> kSignExtendWShift; 940 break; 941 case UXTX: 942 case SXTX: 943 break; 944 default: 945 UNREACHABLE(); 946 } 947 return value << left_shift; 948 } 949 950 951 template <typename T> 952 void Simulator::Extract(Instruction* instr) { 953 unsigned lsb = instr->ImmS(); 954 T op2 = reg<T>(instr->Rm()); 955 T result = op2; 956 957 if (lsb) { 958 T op1 = reg<T>(instr->Rn()); 959 result = op2 >> lsb | (op1 << ((sizeof(T) * 8) - lsb)); 960 } 961 set_reg<T>(instr->Rd(), result); 962 } 963 964 965 template<> double Simulator::FPDefaultNaN<double>() const { 966 return kFP64DefaultNaN; 967 } 968 969 970 template<> float Simulator::FPDefaultNaN<float>() const { 971 return kFP32DefaultNaN; 972 } 973 974 975 void Simulator::FPCompare(double val0, double val1) { 976 AssertSupportedFPCR(); 977 978 // TODO(jbramley): This assumes that the C++ implementation handles 979 // comparisons in the way that we expect (as per AssertSupportedFPCR()). 980 if ((std::isnan(val0) != 0) || (std::isnan(val1) != 0)) { 981 nzcv().SetRawValue(FPUnorderedFlag); 982 } else if (val0 < val1) { 983 nzcv().SetRawValue(FPLessThanFlag); 984 } else if (val0 > val1) { 985 nzcv().SetRawValue(FPGreaterThanFlag); 986 } else if (val0 == val1) { 987 nzcv().SetRawValue(FPEqualFlag); 988 } else { 989 UNREACHABLE(); 990 } 991 LogSystemRegister(NZCV); 992 } 993 994 995 void Simulator::SetBreakpoint(Instruction* location) { 996 for (unsigned i = 0; i < breakpoints_.size(); i++) { 997 if (breakpoints_.at(i).location == location) { 998 PrintF(stream_, 999 "Existing breakpoint at %p was %s\n", 1000 reinterpret_cast<void*>(location), 1001 breakpoints_.at(i).enabled ? "disabled" : "enabled"); 1002 breakpoints_.at(i).enabled = !breakpoints_.at(i).enabled; 1003 return; 1004 } 1005 } 1006 Breakpoint new_breakpoint = {location, true}; 1007 breakpoints_.push_back(new_breakpoint); 1008 PrintF(stream_, 1009 "Set a breakpoint at %p\n", reinterpret_cast<void*>(location)); 1010 } 1011 1012 1013 void Simulator::ListBreakpoints() { 1014 PrintF(stream_, "Breakpoints:\n"); 1015 for (unsigned i = 0; i < breakpoints_.size(); i++) { 1016 PrintF(stream_, "%p : %s\n", 1017 reinterpret_cast<void*>(breakpoints_.at(i).location), 1018 breakpoints_.at(i).enabled ? "enabled" : "disabled"); 1019 } 1020 } 1021 1022 1023 void Simulator::CheckBreakpoints() { 1024 bool hit_a_breakpoint = false; 1025 for (unsigned i = 0; i < breakpoints_.size(); i++) { 1026 if ((breakpoints_.at(i).location == pc_) && 1027 breakpoints_.at(i).enabled) { 1028 hit_a_breakpoint = true; 1029 // Disable this breakpoint. 1030 breakpoints_.at(i).enabled = false; 1031 } 1032 } 1033 if (hit_a_breakpoint) { 1034 PrintF(stream_, "Hit and disabled a breakpoint at %p.\n", 1035 reinterpret_cast<void*>(pc_)); 1036 Debug(); 1037 } 1038 } 1039 1040 1041 void Simulator::CheckBreakNext() { 1042 // If the current instruction is a BL, insert a breakpoint just after it. 1043 if (break_on_next_ && pc_->IsBranchAndLinkToRegister()) { 1044 SetBreakpoint(pc_->following()); 1045 break_on_next_ = false; 1046 } 1047 } 1048 1049 1050 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) { 1051 Instruction* end = start->InstructionAtOffset(count * kInstructionSize); 1052 for (Instruction* pc = start; pc < end; pc = pc->following()) { 1053 disassembler_decoder_->Decode(pc); 1054 } 1055 } 1056 1057 1058 void Simulator::PrintSystemRegisters() { 1059 PrintSystemRegister(NZCV); 1060 PrintSystemRegister(FPCR); 1061 } 1062 1063 1064 void Simulator::PrintRegisters() { 1065 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 1066 PrintRegister(i); 1067 } 1068 } 1069 1070 1071 void Simulator::PrintFPRegisters() { 1072 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 1073 PrintFPRegister(i); 1074 } 1075 } 1076 1077 1078 void Simulator::PrintRegister(unsigned code, Reg31Mode r31mode) { 1079 // Don't print writes into xzr. 1080 if ((code == kZeroRegCode) && (r31mode == Reg31IsZeroRegister)) { 1081 return; 1082 } 1083 1084 // The template is "# x<code>:value". 1085 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s\n", 1086 clr_reg_name, XRegNameForCode(code, r31mode), 1087 clr_reg_value, reg<uint64_t>(code, r31mode), clr_normal); 1088 } 1089 1090 1091 void Simulator::PrintFPRegister(unsigned code, PrintFPRegisterSizes sizes) { 1092 // The template is "# v<code>:bits (d<code>:value, ...)". 1093 1094 DCHECK(sizes != 0); 1095 DCHECK((sizes & kPrintAllFPRegValues) == sizes); 1096 1097 // Print the raw bits. 1098 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (", 1099 clr_fpreg_name, VRegNameForCode(code), 1100 clr_fpreg_value, fpreg<uint64_t>(code), clr_normal); 1101 1102 // Print all requested value interpretations. 1103 bool need_separator = false; 1104 if (sizes & kPrintDRegValue) { 1105 fprintf(stream_, "%s%s%s: %s%g%s", 1106 need_separator ? ", " : "", 1107 clr_fpreg_name, DRegNameForCode(code), 1108 clr_fpreg_value, fpreg<double>(code), clr_normal); 1109 need_separator = true; 1110 } 1111 1112 if (sizes & kPrintSRegValue) { 1113 fprintf(stream_, "%s%s%s: %s%g%s", 1114 need_separator ? ", " : "", 1115 clr_fpreg_name, SRegNameForCode(code), 1116 clr_fpreg_value, fpreg<float>(code), clr_normal); 1117 need_separator = true; 1118 } 1119 1120 // End the value list. 1121 fprintf(stream_, ")\n"); 1122 } 1123 1124 1125 void Simulator::PrintSystemRegister(SystemRegister id) { 1126 switch (id) { 1127 case NZCV: 1128 fprintf(stream_, "# %sNZCV: %sN:%d Z:%d C:%d V:%d%s\n", 1129 clr_flag_name, clr_flag_value, 1130 nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(), 1131 clr_normal); 1132 break; 1133 case FPCR: { 1134 static const char * rmode[] = { 1135 "0b00 (Round to Nearest)", 1136 "0b01 (Round towards Plus Infinity)", 1137 "0b10 (Round towards Minus Infinity)", 1138 "0b11 (Round towards Zero)" 1139 }; 1140 DCHECK(fpcr().RMode() < arraysize(rmode)); 1141 fprintf(stream_, 1142 "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n", 1143 clr_flag_name, clr_flag_value, 1144 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()], 1145 clr_normal); 1146 break; 1147 } 1148 default: 1149 UNREACHABLE(); 1150 } 1151 } 1152 1153 1154 void Simulator::PrintRead(uintptr_t address, 1155 size_t size, 1156 unsigned reg_code) { 1157 USE(size); // Size is unused here. 1158 1159 // The template is "# x<code>:value <- address". 1160 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s", 1161 clr_reg_name, XRegNameForCode(reg_code), 1162 clr_reg_value, reg<uint64_t>(reg_code), clr_normal); 1163 1164 fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n", 1165 clr_memory_address, address, clr_normal); 1166 } 1167 1168 1169 void Simulator::PrintReadFP(uintptr_t address, 1170 size_t size, 1171 unsigned reg_code) { 1172 // The template is "# reg:bits (reg:value) <- address". 1173 switch (size) { 1174 case kSRegSize: 1175 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%gf%s)", 1176 clr_fpreg_name, VRegNameForCode(reg_code), 1177 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal, 1178 clr_fpreg_name, SRegNameForCode(reg_code), 1179 clr_fpreg_value, fpreg<float>(reg_code), clr_normal); 1180 break; 1181 case kDRegSize: 1182 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)", 1183 clr_fpreg_name, VRegNameForCode(reg_code), 1184 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal, 1185 clr_fpreg_name, DRegNameForCode(reg_code), 1186 clr_fpreg_value, fpreg<double>(reg_code), clr_normal); 1187 break; 1188 default: 1189 UNREACHABLE(); 1190 } 1191 1192 fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n", 1193 clr_memory_address, address, clr_normal); 1194 } 1195 1196 1197 void Simulator::PrintWrite(uintptr_t address, 1198 size_t size, 1199 unsigned reg_code) { 1200 // The template is "# reg:value -> address". To keep the trace tidy and 1201 // readable, the value is aligned with the values in the register trace. 1202 switch (size) { 1203 case kByteSizeInBytes: 1204 fprintf(stream_, "# %s%5s<7:0>: %s0x%02" PRIx8 "%s", 1205 clr_reg_name, WRegNameForCode(reg_code), 1206 clr_reg_value, reg<uint8_t>(reg_code), clr_normal); 1207 break; 1208 case kHalfWordSizeInBytes: 1209 fprintf(stream_, "# %s%5s<15:0>: %s0x%04" PRIx16 "%s", 1210 clr_reg_name, WRegNameForCode(reg_code), 1211 clr_reg_value, reg<uint16_t>(reg_code), clr_normal); 1212 break; 1213 case kWRegSize: 1214 fprintf(stream_, "# %s%5s: %s0x%08" PRIx32 "%s", 1215 clr_reg_name, WRegNameForCode(reg_code), 1216 clr_reg_value, reg<uint32_t>(reg_code), clr_normal); 1217 break; 1218 case kXRegSize: 1219 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s", 1220 clr_reg_name, XRegNameForCode(reg_code), 1221 clr_reg_value, reg<uint64_t>(reg_code), clr_normal); 1222 break; 1223 default: 1224 UNREACHABLE(); 1225 } 1226 1227 fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n", 1228 clr_memory_address, address, clr_normal); 1229 } 1230 1231 1232 void Simulator::PrintWriteFP(uintptr_t address, 1233 size_t size, 1234 unsigned reg_code) { 1235 // The template is "# reg:bits (reg:value) -> address". To keep the trace tidy 1236 // and readable, the value is aligned with the values in the register trace. 1237 switch (size) { 1238 case kSRegSize: 1239 fprintf(stream_, "# %s%5s<31:0>: %s0x%08" PRIx32 "%s (%s%s: %s%gf%s)", 1240 clr_fpreg_name, VRegNameForCode(reg_code), 1241 clr_fpreg_value, fpreg<uint32_t>(reg_code), clr_normal, 1242 clr_fpreg_name, SRegNameForCode(reg_code), 1243 clr_fpreg_value, fpreg<float>(reg_code), clr_normal); 1244 break; 1245 case kDRegSize: 1246 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)", 1247 clr_fpreg_name, VRegNameForCode(reg_code), 1248 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal, 1249 clr_fpreg_name, DRegNameForCode(reg_code), 1250 clr_fpreg_value, fpreg<double>(reg_code), clr_normal); 1251 break; 1252 default: 1253 UNREACHABLE(); 1254 } 1255 1256 fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n", 1257 clr_memory_address, address, clr_normal); 1258 } 1259 1260 1261 // Visitors--------------------------------------------------------------------- 1262 1263 void Simulator::VisitUnimplemented(Instruction* instr) { 1264 fprintf(stream_, "Unimplemented instruction at %p: 0x%08" PRIx32 "\n", 1265 reinterpret_cast<void*>(instr), instr->InstructionBits()); 1266 UNIMPLEMENTED(); 1267 } 1268 1269 1270 void Simulator::VisitUnallocated(Instruction* instr) { 1271 fprintf(stream_, "Unallocated instruction at %p: 0x%08" PRIx32 "\n", 1272 reinterpret_cast<void*>(instr), instr->InstructionBits()); 1273 UNIMPLEMENTED(); 1274 } 1275 1276 1277 void Simulator::VisitPCRelAddressing(Instruction* instr) { 1278 switch (instr->Mask(PCRelAddressingMask)) { 1279 case ADR: 1280 set_reg(instr->Rd(), instr->ImmPCOffsetTarget()); 1281 break; 1282 case ADRP: // Not implemented in the assembler. 1283 UNIMPLEMENTED(); 1284 break; 1285 default: 1286 UNREACHABLE(); 1287 break; 1288 } 1289 } 1290 1291 1292 void Simulator::VisitUnconditionalBranch(Instruction* instr) { 1293 switch (instr->Mask(UnconditionalBranchMask)) { 1294 case BL: 1295 set_lr(instr->following()); 1296 // Fall through. 1297 case B: 1298 set_pc(instr->ImmPCOffsetTarget()); 1299 break; 1300 default: 1301 UNREACHABLE(); 1302 } 1303 } 1304 1305 1306 void Simulator::VisitConditionalBranch(Instruction* instr) { 1307 DCHECK(instr->Mask(ConditionalBranchMask) == B_cond); 1308 if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) { 1309 set_pc(instr->ImmPCOffsetTarget()); 1310 } 1311 } 1312 1313 1314 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) { 1315 Instruction* target = reg<Instruction*>(instr->Rn()); 1316 switch (instr->Mask(UnconditionalBranchToRegisterMask)) { 1317 case BLR: { 1318 set_lr(instr->following()); 1319 if (instr->Rn() == 31) { 1320 // BLR XZR is used as a guard for the constant pool. We should never hit 1321 // this, but if we do trap to allow debugging. 1322 Debug(); 1323 } 1324 // Fall through. 1325 } 1326 case BR: 1327 case RET: set_pc(target); break; 1328 default: UNIMPLEMENTED(); 1329 } 1330 } 1331 1332 1333 void Simulator::VisitTestBranch(Instruction* instr) { 1334 unsigned bit_pos = (instr->ImmTestBranchBit5() << 5) | 1335 instr->ImmTestBranchBit40(); 1336 bool take_branch = ((xreg(instr->Rt()) & (1UL << bit_pos)) == 0); 1337 switch (instr->Mask(TestBranchMask)) { 1338 case TBZ: break; 1339 case TBNZ: take_branch = !take_branch; break; 1340 default: UNIMPLEMENTED(); 1341 } 1342 if (take_branch) { 1343 set_pc(instr->ImmPCOffsetTarget()); 1344 } 1345 } 1346 1347 1348 void Simulator::VisitCompareBranch(Instruction* instr) { 1349 unsigned rt = instr->Rt(); 1350 bool take_branch = false; 1351 switch (instr->Mask(CompareBranchMask)) { 1352 case CBZ_w: take_branch = (wreg(rt) == 0); break; 1353 case CBZ_x: take_branch = (xreg(rt) == 0); break; 1354 case CBNZ_w: take_branch = (wreg(rt) != 0); break; 1355 case CBNZ_x: take_branch = (xreg(rt) != 0); break; 1356 default: UNIMPLEMENTED(); 1357 } 1358 if (take_branch) { 1359 set_pc(instr->ImmPCOffsetTarget()); 1360 } 1361 } 1362 1363 1364 template<typename T> 1365 void Simulator::AddSubHelper(Instruction* instr, T op2) { 1366 bool set_flags = instr->FlagsUpdate(); 1367 T new_val = 0; 1368 Instr operation = instr->Mask(AddSubOpMask); 1369 1370 switch (operation) { 1371 case ADD: 1372 case ADDS: { 1373 new_val = AddWithCarry<T>(set_flags, 1374 reg<T>(instr->Rn(), instr->RnMode()), 1375 op2); 1376 break; 1377 } 1378 case SUB: 1379 case SUBS: { 1380 new_val = AddWithCarry<T>(set_flags, 1381 reg<T>(instr->Rn(), instr->RnMode()), 1382 ~op2, 1383 1); 1384 break; 1385 } 1386 default: UNREACHABLE(); 1387 } 1388 1389 set_reg<T>(instr->Rd(), new_val, instr->RdMode()); 1390 } 1391 1392 1393 void Simulator::VisitAddSubShifted(Instruction* instr) { 1394 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); 1395 unsigned shift_amount = instr->ImmDPShift(); 1396 1397 if (instr->SixtyFourBits()) { 1398 int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount); 1399 AddSubHelper(instr, op2); 1400 } else { 1401 int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount); 1402 AddSubHelper(instr, op2); 1403 } 1404 } 1405 1406 1407 void Simulator::VisitAddSubImmediate(Instruction* instr) { 1408 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); 1409 if (instr->SixtyFourBits()) { 1410 AddSubHelper<int64_t>(instr, op2); 1411 } else { 1412 AddSubHelper<int32_t>(instr, op2); 1413 } 1414 } 1415 1416 1417 void Simulator::VisitAddSubExtended(Instruction* instr) { 1418 Extend ext = static_cast<Extend>(instr->ExtendMode()); 1419 unsigned left_shift = instr->ImmExtendShift(); 1420 if (instr->SixtyFourBits()) { 1421 int64_t op2 = ExtendValue(xreg(instr->Rm()), ext, left_shift); 1422 AddSubHelper(instr, op2); 1423 } else { 1424 int32_t op2 = ExtendValue(wreg(instr->Rm()), ext, left_shift); 1425 AddSubHelper(instr, op2); 1426 } 1427 } 1428 1429 1430 void Simulator::VisitAddSubWithCarry(Instruction* instr) { 1431 if (instr->SixtyFourBits()) { 1432 AddSubWithCarry<int64_t>(instr); 1433 } else { 1434 AddSubWithCarry<int32_t>(instr); 1435 } 1436 } 1437 1438 1439 void Simulator::VisitLogicalShifted(Instruction* instr) { 1440 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); 1441 unsigned shift_amount = instr->ImmDPShift(); 1442 1443 if (instr->SixtyFourBits()) { 1444 int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount); 1445 op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2; 1446 LogicalHelper<int64_t>(instr, op2); 1447 } else { 1448 int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount); 1449 op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2; 1450 LogicalHelper<int32_t>(instr, op2); 1451 } 1452 } 1453 1454 1455 void Simulator::VisitLogicalImmediate(Instruction* instr) { 1456 if (instr->SixtyFourBits()) { 1457 LogicalHelper<int64_t>(instr, instr->ImmLogical()); 1458 } else { 1459 LogicalHelper<int32_t>(instr, instr->ImmLogical()); 1460 } 1461 } 1462 1463 1464 template<typename T> 1465 void Simulator::LogicalHelper(Instruction* instr, T op2) { 1466 T op1 = reg<T>(instr->Rn()); 1467 T result = 0; 1468 bool update_flags = false; 1469 1470 // Switch on the logical operation, stripping out the NOT bit, as it has a 1471 // different meaning for logical immediate instructions. 1472 switch (instr->Mask(LogicalOpMask & ~NOT)) { 1473 case ANDS: update_flags = true; // Fall through. 1474 case AND: result = op1 & op2; break; 1475 case ORR: result = op1 | op2; break; 1476 case EOR: result = op1 ^ op2; break; 1477 default: 1478 UNIMPLEMENTED(); 1479 } 1480 1481 if (update_flags) { 1482 nzcv().SetN(CalcNFlag(result)); 1483 nzcv().SetZ(CalcZFlag(result)); 1484 nzcv().SetC(0); 1485 nzcv().SetV(0); 1486 LogSystemRegister(NZCV); 1487 } 1488 1489 set_reg<T>(instr->Rd(), result, instr->RdMode()); 1490 } 1491 1492 1493 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { 1494 if (instr->SixtyFourBits()) { 1495 ConditionalCompareHelper(instr, xreg(instr->Rm())); 1496 } else { 1497 ConditionalCompareHelper(instr, wreg(instr->Rm())); 1498 } 1499 } 1500 1501 1502 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) { 1503 if (instr->SixtyFourBits()) { 1504 ConditionalCompareHelper<int64_t>(instr, instr->ImmCondCmp()); 1505 } else { 1506 ConditionalCompareHelper<int32_t>(instr, instr->ImmCondCmp()); 1507 } 1508 } 1509 1510 1511 template<typename T> 1512 void Simulator::ConditionalCompareHelper(Instruction* instr, T op2) { 1513 T op1 = reg<T>(instr->Rn()); 1514 1515 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 1516 // If the condition passes, set the status flags to the result of comparing 1517 // the operands. 1518 if (instr->Mask(ConditionalCompareMask) == CCMP) { 1519 AddWithCarry<T>(true, op1, ~op2, 1); 1520 } else { 1521 DCHECK(instr->Mask(ConditionalCompareMask) == CCMN); 1522 AddWithCarry<T>(true, op1, op2, 0); 1523 } 1524 } else { 1525 // If the condition fails, set the status flags to the nzcv immediate. 1526 nzcv().SetFlags(instr->Nzcv()); 1527 LogSystemRegister(NZCV); 1528 } 1529 } 1530 1531 1532 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) { 1533 int offset = instr->ImmLSUnsigned() << instr->SizeLS(); 1534 LoadStoreHelper(instr, offset, Offset); 1535 } 1536 1537 1538 void Simulator::VisitLoadStoreUnscaledOffset(Instruction* instr) { 1539 LoadStoreHelper(instr, instr->ImmLS(), Offset); 1540 } 1541 1542 1543 void Simulator::VisitLoadStorePreIndex(Instruction* instr) { 1544 LoadStoreHelper(instr, instr->ImmLS(), PreIndex); 1545 } 1546 1547 1548 void Simulator::VisitLoadStorePostIndex(Instruction* instr) { 1549 LoadStoreHelper(instr, instr->ImmLS(), PostIndex); 1550 } 1551 1552 1553 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) { 1554 Extend ext = static_cast<Extend>(instr->ExtendMode()); 1555 DCHECK((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); 1556 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS(); 1557 1558 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount); 1559 LoadStoreHelper(instr, offset, Offset); 1560 } 1561 1562 1563 void Simulator::LoadStoreHelper(Instruction* instr, 1564 int64_t offset, 1565 AddrMode addrmode) { 1566 unsigned srcdst = instr->Rt(); 1567 unsigned addr_reg = instr->Rn(); 1568 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode); 1569 uintptr_t stack = 0; 1570 1571 // Handle the writeback for stores before the store. On a CPU the writeback 1572 // and the store are atomic, but when running on the simulator it is possible 1573 // to be interrupted in between. The simulator is not thread safe and V8 does 1574 // not require it to be to run JavaScript therefore the profiler may sample 1575 // the "simulated" CPU in the middle of load/store with writeback. The code 1576 // below ensures that push operations are safe even when interrupted: the 1577 // stack pointer will be decremented before adding an element to the stack. 1578 if (instr->IsStore()) { 1579 LoadStoreWriteBack(addr_reg, offset, addrmode); 1580 1581 // For store the address post writeback is used to check access below the 1582 // stack. 1583 stack = sp(); 1584 } 1585 1586 LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask)); 1587 switch (op) { 1588 // Use _no_log variants to suppress the register trace (LOG_REGS, 1589 // LOG_FP_REGS). We will print a more detailed log. 1590 case LDRB_w: set_wreg_no_log(srcdst, MemoryRead<uint8_t>(address)); break; 1591 case LDRH_w: set_wreg_no_log(srcdst, MemoryRead<uint16_t>(address)); break; 1592 case LDR_w: set_wreg_no_log(srcdst, MemoryRead<uint32_t>(address)); break; 1593 case LDR_x: set_xreg_no_log(srcdst, MemoryRead<uint64_t>(address)); break; 1594 case LDRSB_w: set_wreg_no_log(srcdst, MemoryRead<int8_t>(address)); break; 1595 case LDRSH_w: set_wreg_no_log(srcdst, MemoryRead<int16_t>(address)); break; 1596 case LDRSB_x: set_xreg_no_log(srcdst, MemoryRead<int8_t>(address)); break; 1597 case LDRSH_x: set_xreg_no_log(srcdst, MemoryRead<int16_t>(address)); break; 1598 case LDRSW_x: set_xreg_no_log(srcdst, MemoryRead<int32_t>(address)); break; 1599 case LDR_s: set_sreg_no_log(srcdst, MemoryRead<float>(address)); break; 1600 case LDR_d: set_dreg_no_log(srcdst, MemoryRead<double>(address)); break; 1601 1602 case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break; 1603 case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break; 1604 case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break; 1605 case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break; 1606 case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break; 1607 case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break; 1608 1609 default: UNIMPLEMENTED(); 1610 } 1611 1612 // Print a detailed trace (including the memory address) instead of the basic 1613 // register:value trace generated by set_*reg(). 1614 size_t access_size = 1 << instr->SizeLS(); 1615 if (instr->IsLoad()) { 1616 if ((op == LDR_s) || (op == LDR_d)) { 1617 LogReadFP(address, access_size, srcdst); 1618 } else { 1619 LogRead(address, access_size, srcdst); 1620 } 1621 } else { 1622 if ((op == STR_s) || (op == STR_d)) { 1623 LogWriteFP(address, access_size, srcdst); 1624 } else { 1625 LogWrite(address, access_size, srcdst); 1626 } 1627 } 1628 1629 // Handle the writeback for loads after the load to ensure safe pop 1630 // operation even when interrupted in the middle of it. The stack pointer 1631 // is only updated after the load so pop(fp) will never break the invariant 1632 // sp <= fp expected while walking the stack in the sampler. 1633 if (instr->IsLoad()) { 1634 // For loads the address pre writeback is used to check access below the 1635 // stack. 1636 stack = sp(); 1637 1638 LoadStoreWriteBack(addr_reg, offset, addrmode); 1639 } 1640 1641 // Accesses below the stack pointer (but above the platform stack limit) are 1642 // not allowed in the ABI. 1643 CheckMemoryAccess(address, stack); 1644 } 1645 1646 1647 void Simulator::VisitLoadStorePairOffset(Instruction* instr) { 1648 LoadStorePairHelper(instr, Offset); 1649 } 1650 1651 1652 void Simulator::VisitLoadStorePairPreIndex(Instruction* instr) { 1653 LoadStorePairHelper(instr, PreIndex); 1654 } 1655 1656 1657 void Simulator::VisitLoadStorePairPostIndex(Instruction* instr) { 1658 LoadStorePairHelper(instr, PostIndex); 1659 } 1660 1661 1662 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) { 1663 LoadStorePairHelper(instr, Offset); 1664 } 1665 1666 1667 void Simulator::LoadStorePairHelper(Instruction* instr, 1668 AddrMode addrmode) { 1669 unsigned rt = instr->Rt(); 1670 unsigned rt2 = instr->Rt2(); 1671 unsigned addr_reg = instr->Rn(); 1672 size_t access_size = 1 << instr->SizeLSPair(); 1673 int64_t offset = instr->ImmLSPair() * access_size; 1674 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode); 1675 uintptr_t address2 = address + access_size; 1676 uintptr_t stack = 0; 1677 1678 // Handle the writeback for stores before the store. On a CPU the writeback 1679 // and the store are atomic, but when running on the simulator it is possible 1680 // to be interrupted in between. The simulator is not thread safe and V8 does 1681 // not require it to be to run JavaScript therefore the profiler may sample 1682 // the "simulated" CPU in the middle of load/store with writeback. The code 1683 // below ensures that push operations are safe even when interrupted: the 1684 // stack pointer will be decremented before adding an element to the stack. 1685 if (instr->IsStore()) { 1686 LoadStoreWriteBack(addr_reg, offset, addrmode); 1687 1688 // For store the address post writeback is used to check access below the 1689 // stack. 1690 stack = sp(); 1691 } 1692 1693 LoadStorePairOp op = 1694 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); 1695 1696 // 'rt' and 'rt2' can only be aliased for stores. 1697 DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2)); 1698 1699 switch (op) { 1700 // Use _no_log variants to suppress the register trace (LOG_REGS, 1701 // LOG_FP_REGS). We will print a more detailed log. 1702 case LDP_w: { 1703 DCHECK(access_size == kWRegSize); 1704 set_wreg_no_log(rt, MemoryRead<uint32_t>(address)); 1705 set_wreg_no_log(rt2, MemoryRead<uint32_t>(address2)); 1706 break; 1707 } 1708 case LDP_s: { 1709 DCHECK(access_size == kSRegSize); 1710 set_sreg_no_log(rt, MemoryRead<float>(address)); 1711 set_sreg_no_log(rt2, MemoryRead<float>(address2)); 1712 break; 1713 } 1714 case LDP_x: { 1715 DCHECK(access_size == kXRegSize); 1716 set_xreg_no_log(rt, MemoryRead<uint64_t>(address)); 1717 set_xreg_no_log(rt2, MemoryRead<uint64_t>(address2)); 1718 break; 1719 } 1720 case LDP_d: { 1721 DCHECK(access_size == kDRegSize); 1722 set_dreg_no_log(rt, MemoryRead<double>(address)); 1723 set_dreg_no_log(rt2, MemoryRead<double>(address2)); 1724 break; 1725 } 1726 case LDPSW_x: { 1727 DCHECK(access_size == kWRegSize); 1728 set_xreg_no_log(rt, MemoryRead<int32_t>(address)); 1729 set_xreg_no_log(rt2, MemoryRead<int32_t>(address2)); 1730 break; 1731 } 1732 case STP_w: { 1733 DCHECK(access_size == kWRegSize); 1734 MemoryWrite<uint32_t>(address, wreg(rt)); 1735 MemoryWrite<uint32_t>(address2, wreg(rt2)); 1736 break; 1737 } 1738 case STP_s: { 1739 DCHECK(access_size == kSRegSize); 1740 MemoryWrite<float>(address, sreg(rt)); 1741 MemoryWrite<float>(address2, sreg(rt2)); 1742 break; 1743 } 1744 case STP_x: { 1745 DCHECK(access_size == kXRegSize); 1746 MemoryWrite<uint64_t>(address, xreg(rt)); 1747 MemoryWrite<uint64_t>(address2, xreg(rt2)); 1748 break; 1749 } 1750 case STP_d: { 1751 DCHECK(access_size == kDRegSize); 1752 MemoryWrite<double>(address, dreg(rt)); 1753 MemoryWrite<double>(address2, dreg(rt2)); 1754 break; 1755 } 1756 default: UNREACHABLE(); 1757 } 1758 1759 // Print a detailed trace (including the memory address) instead of the basic 1760 // register:value trace generated by set_*reg(). 1761 if (instr->IsLoad()) { 1762 if ((op == LDP_s) || (op == LDP_d)) { 1763 LogReadFP(address, access_size, rt); 1764 LogReadFP(address2, access_size, rt2); 1765 } else { 1766 LogRead(address, access_size, rt); 1767 LogRead(address2, access_size, rt2); 1768 } 1769 } else { 1770 if ((op == STP_s) || (op == STP_d)) { 1771 LogWriteFP(address, access_size, rt); 1772 LogWriteFP(address2, access_size, rt2); 1773 } else { 1774 LogWrite(address, access_size, rt); 1775 LogWrite(address2, access_size, rt2); 1776 } 1777 } 1778 1779 // Handle the writeback for loads after the load to ensure safe pop 1780 // operation even when interrupted in the middle of it. The stack pointer 1781 // is only updated after the load so pop(fp) will never break the invariant 1782 // sp <= fp expected while walking the stack in the sampler. 1783 if (instr->IsLoad()) { 1784 // For loads the address pre writeback is used to check access below the 1785 // stack. 1786 stack = sp(); 1787 1788 LoadStoreWriteBack(addr_reg, offset, addrmode); 1789 } 1790 1791 // Accesses below the stack pointer (but above the platform stack limit) are 1792 // not allowed in the ABI. 1793 CheckMemoryAccess(address, stack); 1794 } 1795 1796 1797 void Simulator::VisitLoadLiteral(Instruction* instr) { 1798 uintptr_t address = instr->LiteralAddress(); 1799 unsigned rt = instr->Rt(); 1800 1801 switch (instr->Mask(LoadLiteralMask)) { 1802 // Use _no_log variants to suppress the register trace (LOG_REGS, 1803 // LOG_FP_REGS), then print a more detailed log. 1804 case LDR_w_lit: 1805 set_wreg_no_log(rt, MemoryRead<uint32_t>(address)); 1806 LogRead(address, kWRegSize, rt); 1807 break; 1808 case LDR_x_lit: 1809 set_xreg_no_log(rt, MemoryRead<uint64_t>(address)); 1810 LogRead(address, kXRegSize, rt); 1811 break; 1812 case LDR_s_lit: 1813 set_sreg_no_log(rt, MemoryRead<float>(address)); 1814 LogReadFP(address, kSRegSize, rt); 1815 break; 1816 case LDR_d_lit: 1817 set_dreg_no_log(rt, MemoryRead<double>(address)); 1818 LogReadFP(address, kDRegSize, rt); 1819 break; 1820 default: UNREACHABLE(); 1821 } 1822 } 1823 1824 1825 uintptr_t Simulator::LoadStoreAddress(unsigned addr_reg, int64_t offset, 1826 AddrMode addrmode) { 1827 const unsigned kSPRegCode = kSPRegInternalCode & kRegCodeMask; 1828 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 1829 if ((addr_reg == kSPRegCode) && ((address % 16) != 0)) { 1830 // When the base register is SP the stack pointer is required to be 1831 // quadword aligned prior to the address calculation and write-backs. 1832 // Misalignment will cause a stack alignment fault. 1833 FATAL("ALIGNMENT EXCEPTION"); 1834 } 1835 1836 if ((addrmode == Offset) || (addrmode == PreIndex)) { 1837 address += offset; 1838 } 1839 1840 return address; 1841 } 1842 1843 1844 void Simulator::LoadStoreWriteBack(unsigned addr_reg, 1845 int64_t offset, 1846 AddrMode addrmode) { 1847 if ((addrmode == PreIndex) || (addrmode == PostIndex)) { 1848 DCHECK(offset != 0); 1849 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 1850 set_reg(addr_reg, address + offset, Reg31IsStackPointer); 1851 } 1852 } 1853 1854 1855 void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) { 1856 if ((address >= stack_limit_) && (address < stack)) { 1857 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n"); 1858 fprintf(stream_, " sp is here: 0x%016" PRIx64 "\n", 1859 static_cast<uint64_t>(stack)); 1860 fprintf(stream_, " access was here: 0x%016" PRIx64 "\n", 1861 static_cast<uint64_t>(address)); 1862 fprintf(stream_, " stack limit is here: 0x%016" PRIx64 "\n", 1863 static_cast<uint64_t>(stack_limit_)); 1864 fprintf(stream_, "\n"); 1865 FATAL("ACCESS BELOW STACK POINTER"); 1866 } 1867 } 1868 1869 1870 void Simulator::VisitMoveWideImmediate(Instruction* instr) { 1871 MoveWideImmediateOp mov_op = 1872 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); 1873 int64_t new_xn_val = 0; 1874 1875 bool is_64_bits = instr->SixtyFourBits() == 1; 1876 // Shift is limited for W operations. 1877 DCHECK(is_64_bits || (instr->ShiftMoveWide() < 2)); 1878 1879 // Get the shifted immediate. 1880 int64_t shift = instr->ShiftMoveWide() * 16; 1881 int64_t shifted_imm16 = instr->ImmMoveWide() << shift; 1882 1883 // Compute the new value. 1884 switch (mov_op) { 1885 case MOVN_w: 1886 case MOVN_x: { 1887 new_xn_val = ~shifted_imm16; 1888 if (!is_64_bits) new_xn_val &= kWRegMask; 1889 break; 1890 } 1891 case MOVK_w: 1892 case MOVK_x: { 1893 unsigned reg_code = instr->Rd(); 1894 int64_t prev_xn_val = is_64_bits ? xreg(reg_code) 1895 : wreg(reg_code); 1896 new_xn_val = (prev_xn_val & ~(0xffffL << shift)) | shifted_imm16; 1897 break; 1898 } 1899 case MOVZ_w: 1900 case MOVZ_x: { 1901 new_xn_val = shifted_imm16; 1902 break; 1903 } 1904 default: 1905 UNREACHABLE(); 1906 } 1907 1908 // Update the destination register. 1909 set_xreg(instr->Rd(), new_xn_val); 1910 } 1911 1912 1913 void Simulator::VisitConditionalSelect(Instruction* instr) { 1914 if (ConditionFailed(static_cast<Condition>(instr->Condition()))) { 1915 uint64_t new_val = xreg(instr->Rm()); 1916 switch (instr->Mask(ConditionalSelectMask)) { 1917 case CSEL_w: set_wreg(instr->Rd(), new_val); break; 1918 case CSEL_x: set_xreg(instr->Rd(), new_val); break; 1919 case CSINC_w: set_wreg(instr->Rd(), new_val + 1); break; 1920 case CSINC_x: set_xreg(instr->Rd(), new_val + 1); break; 1921 case CSINV_w: set_wreg(instr->Rd(), ~new_val); break; 1922 case CSINV_x: set_xreg(instr->Rd(), ~new_val); break; 1923 case CSNEG_w: set_wreg(instr->Rd(), -new_val); break; 1924 case CSNEG_x: set_xreg(instr->Rd(), -new_val); break; 1925 default: UNIMPLEMENTED(); 1926 } 1927 } else { 1928 if (instr->SixtyFourBits()) { 1929 set_xreg(instr->Rd(), xreg(instr->Rn())); 1930 } else { 1931 set_wreg(instr->Rd(), wreg(instr->Rn())); 1932 } 1933 } 1934 } 1935 1936 1937 void Simulator::VisitDataProcessing1Source(Instruction* instr) { 1938 unsigned dst = instr->Rd(); 1939 unsigned src = instr->Rn(); 1940 1941 switch (instr->Mask(DataProcessing1SourceMask)) { 1942 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break; 1943 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break; 1944 case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break; 1945 case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break; 1946 case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break; 1947 case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break; 1948 case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break; 1949 case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSizeInBits)); 1950 break; 1951 case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSizeInBits)); 1952 break; 1953 case CLS_w: { 1954 set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSizeInBits)); 1955 break; 1956 } 1957 case CLS_x: { 1958 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits)); 1959 break; 1960 } 1961 default: UNIMPLEMENTED(); 1962 } 1963 } 1964 1965 1966 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { 1967 DCHECK((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits)); 1968 uint64_t result = 0; 1969 for (unsigned i = 0; i < num_bits; i++) { 1970 result = (result << 1) | (value & 1); 1971 value >>= 1; 1972 } 1973 return result; 1974 } 1975 1976 1977 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { 1978 // Split the 64-bit value into an 8-bit array, where b[0] is the least 1979 // significant byte, and b[7] is the most significant. 1980 uint8_t bytes[8]; 1981 uint64_t mask = 0xff00000000000000UL; 1982 for (int i = 7; i >= 0; i--) { 1983 bytes[i] = (value & mask) >> (i * 8); 1984 mask >>= 8; 1985 } 1986 1987 // Permutation tables for REV instructions. 1988 // permute_table[Reverse16] is used by REV16_x, REV16_w 1989 // permute_table[Reverse32] is used by REV32_x, REV_w 1990 // permute_table[Reverse64] is used by REV_x 1991 DCHECK((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2)); 1992 static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1}, 1993 {4, 5, 6, 7, 0, 1, 2, 3}, 1994 {0, 1, 2, 3, 4, 5, 6, 7} }; 1995 uint64_t result = 0; 1996 for (int i = 0; i < 8; i++) { 1997 result <<= 8; 1998 result |= bytes[permute_table[mode][i]]; 1999 } 2000 return result; 2001 } 2002 2003 2004 template <typename T> 2005 void Simulator::DataProcessing2Source(Instruction* instr) { 2006 Shift shift_op = NO_SHIFT; 2007 T result = 0; 2008 switch (instr->Mask(DataProcessing2SourceMask)) { 2009 case SDIV_w: 2010 case SDIV_x: { 2011 T rn = reg<T>(instr->Rn()); 2012 T rm = reg<T>(instr->Rm()); 2013 if ((rn == std::numeric_limits<T>::min()) && (rm == -1)) { 2014 result = std::numeric_limits<T>::min(); 2015 } else if (rm == 0) { 2016 // Division by zero can be trapped, but not on A-class processors. 2017 result = 0; 2018 } else { 2019 result = rn / rm; 2020 } 2021 break; 2022 } 2023 case UDIV_w: 2024 case UDIV_x: { 2025 typedef typename make_unsigned<T>::type unsignedT; 2026 unsignedT rn = static_cast<unsignedT>(reg<T>(instr->Rn())); 2027 unsignedT rm = static_cast<unsignedT>(reg<T>(instr->Rm())); 2028 if (rm == 0) { 2029 // Division by zero can be trapped, but not on A-class processors. 2030 result = 0; 2031 } else { 2032 result = rn / rm; 2033 } 2034 break; 2035 } 2036 case LSLV_w: 2037 case LSLV_x: shift_op = LSL; break; 2038 case LSRV_w: 2039 case LSRV_x: shift_op = LSR; break; 2040 case ASRV_w: 2041 case ASRV_x: shift_op = ASR; break; 2042 case RORV_w: 2043 case RORV_x: shift_op = ROR; break; 2044 default: UNIMPLEMENTED(); 2045 } 2046 2047 if (shift_op != NO_SHIFT) { 2048 // Shift distance encoded in the least-significant five/six bits of the 2049 // register. 2050 unsigned shift = wreg(instr->Rm()); 2051 if (sizeof(T) == kWRegSize) { 2052 shift &= kShiftAmountWRegMask; 2053 } else { 2054 shift &= kShiftAmountXRegMask; 2055 } 2056 result = ShiftOperand(reg<T>(instr->Rn()), shift_op, shift); 2057 } 2058 set_reg<T>(instr->Rd(), result); 2059 } 2060 2061 2062 void Simulator::VisitDataProcessing2Source(Instruction* instr) { 2063 if (instr->SixtyFourBits()) { 2064 DataProcessing2Source<int64_t>(instr); 2065 } else { 2066 DataProcessing2Source<int32_t>(instr); 2067 } 2068 } 2069 2070 2071 // The algorithm used is described in section 8.2 of 2072 // Hacker's Delight, by Henry S. Warren, Jr. 2073 // It assumes that a right shift on a signed integer is an arithmetic shift. 2074 static int64_t MultiplyHighSigned(int64_t u, int64_t v) { 2075 uint64_t u0, v0, w0; 2076 int64_t u1, v1, w1, w2, t; 2077 2078 u0 = u & 0xffffffffL; 2079 u1 = u >> 32; 2080 v0 = v & 0xffffffffL; 2081 v1 = v >> 32; 2082 2083 w0 = u0 * v0; 2084 t = u1 * v0 + (w0 >> 32); 2085 w1 = t & 0xffffffffL; 2086 w2 = t >> 32; 2087 w1 = u0 * v1 + w1; 2088 2089 return u1 * v1 + w2 + (w1 >> 32); 2090 } 2091 2092 2093 void Simulator::VisitDataProcessing3Source(Instruction* instr) { 2094 int64_t result = 0; 2095 // Extract and sign- or zero-extend 32-bit arguments for widening operations. 2096 uint64_t rn_u32 = reg<uint32_t>(instr->Rn()); 2097 uint64_t rm_u32 = reg<uint32_t>(instr->Rm()); 2098 int64_t rn_s32 = reg<int32_t>(instr->Rn()); 2099 int64_t rm_s32 = reg<int32_t>(instr->Rm()); 2100 switch (instr->Mask(DataProcessing3SourceMask)) { 2101 case MADD_w: 2102 case MADD_x: 2103 result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm())); 2104 break; 2105 case MSUB_w: 2106 case MSUB_x: 2107 result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm())); 2108 break; 2109 case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break; 2110 case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break; 2111 case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break; 2112 case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break; 2113 case SMULH_x: 2114 DCHECK(instr->Ra() == kZeroRegCode); 2115 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); 2116 break; 2117 default: UNIMPLEMENTED(); 2118 } 2119 2120 if (instr->SixtyFourBits()) { 2121 set_xreg(instr->Rd(), result); 2122 } else { 2123 set_wreg(instr->Rd(), result); 2124 } 2125 } 2126 2127 2128 template <typename T> 2129 void Simulator::BitfieldHelper(Instruction* instr) { 2130 typedef typename make_unsigned<T>::type unsignedT; 2131 T reg_size = sizeof(T) * 8; 2132 T R = instr->ImmR(); 2133 T S = instr->ImmS(); 2134 T diff = S - R; 2135 T mask; 2136 if (diff >= 0) { 2137 mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1 2138 : static_cast<T>(-1); 2139 } else { 2140 mask = ((1L << (S + 1)) - 1); 2141 mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R)); 2142 diff += reg_size; 2143 } 2144 2145 // inzero indicates if the extracted bitfield is inserted into the 2146 // destination register value or in zero. 2147 // If extend is true, extend the sign of the extracted bitfield. 2148 bool inzero = false; 2149 bool extend = false; 2150 switch (instr->Mask(BitfieldMask)) { 2151 case BFM_x: 2152 case BFM_w: 2153 break; 2154 case SBFM_x: 2155 case SBFM_w: 2156 inzero = true; 2157 extend = true; 2158 break; 2159 case UBFM_x: 2160 case UBFM_w: 2161 inzero = true; 2162 break; 2163 default: 2164 UNIMPLEMENTED(); 2165 } 2166 2167 T dst = inzero ? 0 : reg<T>(instr->Rd()); 2168 T src = reg<T>(instr->Rn()); 2169 // Rotate source bitfield into place. 2170 T result = (static_cast<unsignedT>(src) >> R) | (src << (reg_size - R)); 2171 // Determine the sign extension. 2172 T topbits_preshift = (static_cast<T>(1) << (reg_size - diff - 1)) - 1; 2173 T signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0) 2174 << (diff + 1); 2175 2176 // Merge sign extension, dest/zero and bitfield. 2177 result = signbits | (result & mask) | (dst & ~mask); 2178 2179 set_reg<T>(instr->Rd(), result); 2180 } 2181 2182 2183 void Simulator::VisitBitfield(Instruction* instr) { 2184 if (instr->SixtyFourBits()) { 2185 BitfieldHelper<int64_t>(instr); 2186 } else { 2187 BitfieldHelper<int32_t>(instr); 2188 } 2189 } 2190 2191 2192 void Simulator::VisitExtract(Instruction* instr) { 2193 if (instr->SixtyFourBits()) { 2194 Extract<uint64_t>(instr); 2195 } else { 2196 Extract<uint32_t>(instr); 2197 } 2198 } 2199 2200 2201 void Simulator::VisitFPImmediate(Instruction* instr) { 2202 AssertSupportedFPCR(); 2203 2204 unsigned dest = instr->Rd(); 2205 switch (instr->Mask(FPImmediateMask)) { 2206 case FMOV_s_imm: set_sreg(dest, instr->ImmFP32()); break; 2207 case FMOV_d_imm: set_dreg(dest, instr->ImmFP64()); break; 2208 default: UNREACHABLE(); 2209 } 2210 } 2211 2212 2213 void Simulator::VisitFPIntegerConvert(Instruction* instr) { 2214 AssertSupportedFPCR(); 2215 2216 unsigned dst = instr->Rd(); 2217 unsigned src = instr->Rn(); 2218 2219 FPRounding round = fpcr().RMode(); 2220 2221 switch (instr->Mask(FPIntegerConvertMask)) { 2222 case FCVTAS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieAway)); break; 2223 case FCVTAS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieAway)); break; 2224 case FCVTAS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieAway)); break; 2225 case FCVTAS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieAway)); break; 2226 case FCVTAU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieAway)); break; 2227 case FCVTAU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieAway)); break; 2228 case FCVTAU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieAway)); break; 2229 case FCVTAU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieAway)); break; 2230 case FCVTMS_ws: 2231 set_wreg(dst, FPToInt32(sreg(src), FPNegativeInfinity)); 2232 break; 2233 case FCVTMS_xs: 2234 set_xreg(dst, FPToInt64(sreg(src), FPNegativeInfinity)); 2235 break; 2236 case FCVTMS_wd: 2237 set_wreg(dst, FPToInt32(dreg(src), FPNegativeInfinity)); 2238 break; 2239 case FCVTMS_xd: 2240 set_xreg(dst, FPToInt64(dreg(src), FPNegativeInfinity)); 2241 break; 2242 case FCVTMU_ws: 2243 set_wreg(dst, FPToUInt32(sreg(src), FPNegativeInfinity)); 2244 break; 2245 case FCVTMU_xs: 2246 set_xreg(dst, FPToUInt64(sreg(src), FPNegativeInfinity)); 2247 break; 2248 case FCVTMU_wd: 2249 set_wreg(dst, FPToUInt32(dreg(src), FPNegativeInfinity)); 2250 break; 2251 case FCVTMU_xd: 2252 set_xreg(dst, FPToUInt64(dreg(src), FPNegativeInfinity)); 2253 break; 2254 case FCVTNS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieEven)); break; 2255 case FCVTNS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieEven)); break; 2256 case FCVTNS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieEven)); break; 2257 case FCVTNS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieEven)); break; 2258 case FCVTNU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieEven)); break; 2259 case FCVTNU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieEven)); break; 2260 case FCVTNU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieEven)); break; 2261 case FCVTNU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieEven)); break; 2262 case FCVTZS_ws: set_wreg(dst, FPToInt32(sreg(src), FPZero)); break; 2263 case FCVTZS_xs: set_xreg(dst, FPToInt64(sreg(src), FPZero)); break; 2264 case FCVTZS_wd: set_wreg(dst, FPToInt32(dreg(src), FPZero)); break; 2265 case FCVTZS_xd: set_xreg(dst, FPToInt64(dreg(src), FPZero)); break; 2266 case FCVTZU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPZero)); break; 2267 case FCVTZU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPZero)); break; 2268 case FCVTZU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPZero)); break; 2269 case FCVTZU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPZero)); break; 2270 case FMOV_ws: set_wreg(dst, sreg_bits(src)); break; 2271 case FMOV_xd: set_xreg(dst, dreg_bits(src)); break; 2272 case FMOV_sw: set_sreg_bits(dst, wreg(src)); break; 2273 case FMOV_dx: set_dreg_bits(dst, xreg(src)); break; 2274 2275 // A 32-bit input can be handled in the same way as a 64-bit input, since 2276 // the sign- or zero-extension will not affect the conversion. 2277 case SCVTF_dx: set_dreg(dst, FixedToDouble(xreg(src), 0, round)); break; 2278 case SCVTF_dw: set_dreg(dst, FixedToDouble(wreg(src), 0, round)); break; 2279 case UCVTF_dx: set_dreg(dst, UFixedToDouble(xreg(src), 0, round)); break; 2280 case UCVTF_dw: { 2281 set_dreg(dst, UFixedToDouble(reg<uint32_t>(src), 0, round)); 2282 break; 2283 } 2284 case SCVTF_sx: set_sreg(dst, FixedToFloat(xreg(src), 0, round)); break; 2285 case SCVTF_sw: set_sreg(dst, FixedToFloat(wreg(src), 0, round)); break; 2286 case UCVTF_sx: set_sreg(dst, UFixedToFloat(xreg(src), 0, round)); break; 2287 case UCVTF_sw: { 2288 set_sreg(dst, UFixedToFloat(reg<uint32_t>(src), 0, round)); 2289 break; 2290 } 2291 2292 default: UNREACHABLE(); 2293 } 2294 } 2295 2296 2297 void Simulator::VisitFPFixedPointConvert(Instruction* instr) { 2298 AssertSupportedFPCR(); 2299 2300 unsigned dst = instr->Rd(); 2301 unsigned src = instr->Rn(); 2302 int fbits = 64 - instr->FPScale(); 2303 2304 FPRounding round = fpcr().RMode(); 2305 2306 switch (instr->Mask(FPFixedPointConvertMask)) { 2307 // A 32-bit input can be handled in the same way as a 64-bit input, since 2308 // the sign- or zero-extension will not affect the conversion. 2309 case SCVTF_dx_fixed: 2310 set_dreg(dst, FixedToDouble(xreg(src), fbits, round)); 2311 break; 2312 case SCVTF_dw_fixed: 2313 set_dreg(dst, FixedToDouble(wreg(src), fbits, round)); 2314 break; 2315 case UCVTF_dx_fixed: 2316 set_dreg(dst, UFixedToDouble(xreg(src), fbits, round)); 2317 break; 2318 case UCVTF_dw_fixed: { 2319 set_dreg(dst, 2320 UFixedToDouble(reg<uint32_t>(src), fbits, round)); 2321 break; 2322 } 2323 case SCVTF_sx_fixed: 2324 set_sreg(dst, FixedToFloat(xreg(src), fbits, round)); 2325 break; 2326 case SCVTF_sw_fixed: 2327 set_sreg(dst, FixedToFloat(wreg(src), fbits, round)); 2328 break; 2329 case UCVTF_sx_fixed: 2330 set_sreg(dst, UFixedToFloat(xreg(src), fbits, round)); 2331 break; 2332 case UCVTF_sw_fixed: { 2333 set_sreg(dst, 2334 UFixedToFloat(reg<uint32_t>(src), fbits, round)); 2335 break; 2336 } 2337 default: UNREACHABLE(); 2338 } 2339 } 2340 2341 2342 int32_t Simulator::FPToInt32(double value, FPRounding rmode) { 2343 value = FPRoundInt(value, rmode); 2344 if (value >= kWMaxInt) { 2345 return kWMaxInt; 2346 } else if (value < kWMinInt) { 2347 return kWMinInt; 2348 } 2349 return std::isnan(value) ? 0 : static_cast<int32_t>(value); 2350 } 2351 2352 2353 int64_t Simulator::FPToInt64(double value, FPRounding rmode) { 2354 value = FPRoundInt(value, rmode); 2355 if (value >= kXMaxInt) { 2356 return kXMaxInt; 2357 } else if (value < kXMinInt) { 2358 return kXMinInt; 2359 } 2360 return std::isnan(value) ? 0 : static_cast<int64_t>(value); 2361 } 2362 2363 2364 uint32_t Simulator::FPToUInt32(double value, FPRounding rmode) { 2365 value = FPRoundInt(value, rmode); 2366 if (value >= kWMaxUInt) { 2367 return kWMaxUInt; 2368 } else if (value < 0.0) { 2369 return 0; 2370 } 2371 return std::isnan(value) ? 0 : static_cast<uint32_t>(value); 2372 } 2373 2374 2375 uint64_t Simulator::FPToUInt64(double value, FPRounding rmode) { 2376 value = FPRoundInt(value, rmode); 2377 if (value >= kXMaxUInt) { 2378 return kXMaxUInt; 2379 } else if (value < 0.0) { 2380 return 0; 2381 } 2382 return std::isnan(value) ? 0 : static_cast<uint64_t>(value); 2383 } 2384 2385 2386 void Simulator::VisitFPCompare(Instruction* instr) { 2387 AssertSupportedFPCR(); 2388 2389 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits 2390 : kSRegSizeInBits; 2391 double fn_val = fpreg(reg_size, instr->Rn()); 2392 2393 switch (instr->Mask(FPCompareMask)) { 2394 case FCMP_s: 2395 case FCMP_d: FPCompare(fn_val, fpreg(reg_size, instr->Rm())); break; 2396 case FCMP_s_zero: 2397 case FCMP_d_zero: FPCompare(fn_val, 0.0); break; 2398 default: UNIMPLEMENTED(); 2399 } 2400 } 2401 2402 2403 void Simulator::VisitFPConditionalCompare(Instruction* instr) { 2404 AssertSupportedFPCR(); 2405 2406 switch (instr->Mask(FPConditionalCompareMask)) { 2407 case FCCMP_s: 2408 case FCCMP_d: { 2409 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 2410 // If the condition passes, set the status flags to the result of 2411 // comparing the operands. 2412 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits 2413 : kSRegSizeInBits; 2414 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm())); 2415 } else { 2416 // If the condition fails, set the status flags to the nzcv immediate. 2417 nzcv().SetFlags(instr->Nzcv()); 2418 LogSystemRegister(NZCV); 2419 } 2420 break; 2421 } 2422 default: UNIMPLEMENTED(); 2423 } 2424 } 2425 2426 2427 void Simulator::VisitFPConditionalSelect(Instruction* instr) { 2428 AssertSupportedFPCR(); 2429 2430 Instr selected; 2431 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 2432 selected = instr->Rn(); 2433 } else { 2434 selected = instr->Rm(); 2435 } 2436 2437 switch (instr->Mask(FPConditionalSelectMask)) { 2438 case FCSEL_s: set_sreg(instr->Rd(), sreg(selected)); break; 2439 case FCSEL_d: set_dreg(instr->Rd(), dreg(selected)); break; 2440 default: UNIMPLEMENTED(); 2441 } 2442 } 2443 2444 2445 void Simulator::VisitFPDataProcessing1Source(Instruction* instr) { 2446 AssertSupportedFPCR(); 2447 2448 unsigned fd = instr->Rd(); 2449 unsigned fn = instr->Rn(); 2450 2451 switch (instr->Mask(FPDataProcessing1SourceMask)) { 2452 case FMOV_s: set_sreg(fd, sreg(fn)); break; 2453 case FMOV_d: set_dreg(fd, dreg(fn)); break; 2454 case FABS_s: set_sreg(fd, std::fabs(sreg(fn))); break; 2455 case FABS_d: set_dreg(fd, std::fabs(dreg(fn))); break; 2456 case FNEG_s: set_sreg(fd, -sreg(fn)); break; 2457 case FNEG_d: set_dreg(fd, -dreg(fn)); break; 2458 case FSQRT_s: set_sreg(fd, FPSqrt(sreg(fn))); break; 2459 case FSQRT_d: set_dreg(fd, FPSqrt(dreg(fn))); break; 2460 case FRINTA_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieAway)); break; 2461 case FRINTA_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieAway)); break; 2462 case FRINTM_s: 2463 set_sreg(fd, FPRoundInt(sreg(fn), FPNegativeInfinity)); break; 2464 case FRINTM_d: 2465 set_dreg(fd, FPRoundInt(dreg(fn), FPNegativeInfinity)); break; 2466 case FRINTN_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieEven)); break; 2467 case FRINTN_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieEven)); break; 2468 case FRINTZ_s: set_sreg(fd, FPRoundInt(sreg(fn), FPZero)); break; 2469 case FRINTZ_d: set_dreg(fd, FPRoundInt(dreg(fn), FPZero)); break; 2470 case FCVT_ds: set_dreg(fd, FPToDouble(sreg(fn))); break; 2471 case FCVT_sd: set_sreg(fd, FPToFloat(dreg(fn), FPTieEven)); break; 2472 default: UNIMPLEMENTED(); 2473 } 2474 } 2475 2476 2477 // Assemble the specified IEEE-754 components into the target type and apply 2478 // appropriate rounding. 2479 // sign: 0 = positive, 1 = negative 2480 // exponent: Unbiased IEEE-754 exponent. 2481 // mantissa: The mantissa of the input. The top bit (which is not encoded for 2482 // normal IEEE-754 values) must not be omitted. This bit has the 2483 // value 'pow(2, exponent)'. 2484 // 2485 // The input value is assumed to be a normalized value. That is, the input may 2486 // not be infinity or NaN. If the source value is subnormal, it must be 2487 // normalized before calling this function such that the highest set bit in the 2488 // mantissa has the value 'pow(2, exponent)'. 2489 // 2490 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than 2491 // calling a templated FPRound. 2492 template <class T, int ebits, int mbits> 2493 static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, 2494 FPRounding round_mode) { 2495 DCHECK((sign == 0) || (sign == 1)); 2496 2497 // Only the FPTieEven rounding mode is implemented. 2498 DCHECK(round_mode == FPTieEven); 2499 USE(round_mode); 2500 2501 // Rounding can promote subnormals to normals, and normals to infinities. For 2502 // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be 2503 // encodable as a float, but rounding based on the low-order mantissa bits 2504 // could make it overflow. With ties-to-even rounding, this value would become 2505 // an infinity. 2506 2507 // ---- Rounding Method ---- 2508 // 2509 // The exponent is irrelevant in the rounding operation, so we treat the 2510 // lowest-order bit that will fit into the result ('onebit') as having 2511 // the value '1'. Similarly, the highest-order bit that won't fit into 2512 // the result ('halfbit') has the value '0.5'. The 'point' sits between 2513 // 'onebit' and 'halfbit': 2514 // 2515 // These bits fit into the result. 2516 // |---------------------| 2517 // mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2518 // || 2519 // / | 2520 // / halfbit 2521 // onebit 2522 // 2523 // For subnormal outputs, the range of representable bits is smaller and 2524 // the position of onebit and halfbit depends on the exponent of the 2525 // input, but the method is otherwise similar. 2526 // 2527 // onebit(frac) 2528 // | 2529 // | halfbit(frac) halfbit(adjusted) 2530 // | / / 2531 // | | | 2532 // 0b00.0 (exact) -> 0b00.0 (exact) -> 0b00 2533 // 0b00.0... -> 0b00.0... -> 0b00 2534 // 0b00.1 (exact) -> 0b00.0111..111 -> 0b00 2535 // 0b00.1... -> 0b00.1... -> 0b01 2536 // 0b01.0 (exact) -> 0b01.0 (exact) -> 0b01 2537 // 0b01.0... -> 0b01.0... -> 0b01 2538 // 0b01.1 (exact) -> 0b01.1 (exact) -> 0b10 2539 // 0b01.1... -> 0b01.1... -> 0b10 2540 // 0b10.0 (exact) -> 0b10.0 (exact) -> 0b10 2541 // 0b10.0... -> 0b10.0... -> 0b10 2542 // 0b10.1 (exact) -> 0b10.0111..111 -> 0b10 2543 // 0b10.1... -> 0b10.1... -> 0b11 2544 // 0b11.0 (exact) -> 0b11.0 (exact) -> 0b11 2545 // ... / | / | 2546 // / | / | 2547 // / | 2548 // adjusted = frac - (halfbit(mantissa) & ~onebit(frac)); / | 2549 // 2550 // mantissa = (mantissa >> shift) + halfbit(adjusted); 2551 2552 static const int mantissa_offset = 0; 2553 static const int exponent_offset = mantissa_offset + mbits; 2554 static const int sign_offset = exponent_offset + ebits; 2555 STATIC_ASSERT(sign_offset == (sizeof(T) * kByteSize - 1)); 2556 2557 // Bail out early for zero inputs. 2558 if (mantissa == 0) { 2559 return sign << sign_offset; 2560 } 2561 2562 // If all bits in the exponent are set, the value is infinite or NaN. 2563 // This is true for all binary IEEE-754 formats. 2564 static const int infinite_exponent = (1 << ebits) - 1; 2565 static const int max_normal_exponent = infinite_exponent - 1; 2566 2567 // Apply the exponent bias to encode it for the result. Doing this early makes 2568 // it easy to detect values that will be infinite or subnormal. 2569 exponent += max_normal_exponent >> 1; 2570 2571 if (exponent > max_normal_exponent) { 2572 // Overflow: The input is too large for the result type to represent. The 2573 // FPTieEven rounding mode handles overflows using infinities. 2574 exponent = infinite_exponent; 2575 mantissa = 0; 2576 return (sign << sign_offset) | 2577 (exponent << exponent_offset) | 2578 (mantissa << mantissa_offset); 2579 } 2580 2581 // Calculate the shift required to move the top mantissa bit to the proper 2582 // place in the destination type. 2583 const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64); 2584 int shift = highest_significant_bit - mbits; 2585 2586 if (exponent <= 0) { 2587 // The output will be subnormal (before rounding). 2588 2589 // For subnormal outputs, the shift must be adjusted by the exponent. The +1 2590 // is necessary because the exponent of a subnormal value (encoded as 0) is 2591 // the same as the exponent of the smallest normal value (encoded as 1). 2592 shift += -exponent + 1; 2593 2594 // Handle inputs that would produce a zero output. 2595 // 2596 // Shifts higher than highest_significant_bit+1 will always produce a zero 2597 // result. A shift of exactly highest_significant_bit+1 might produce a 2598 // non-zero result after rounding. 2599 if (shift > (highest_significant_bit + 1)) { 2600 // The result will always be +/-0.0. 2601 return sign << sign_offset; 2602 } 2603 2604 // Properly encode the exponent for a subnormal output. 2605 exponent = 0; 2606 } else { 2607 // Clear the topmost mantissa bit, since this is not encoded in IEEE-754 2608 // normal values. 2609 mantissa &= ~(1UL << highest_significant_bit); 2610 } 2611 2612 if (shift > 0) { 2613 // We have to shift the mantissa to the right. Some precision is lost, so we 2614 // need to apply rounding. 2615 uint64_t onebit_mantissa = (mantissa >> (shift)) & 1; 2616 uint64_t halfbit_mantissa = (mantissa >> (shift-1)) & 1; 2617 uint64_t adjusted = mantissa - (halfbit_mantissa & ~onebit_mantissa); 2618 T halfbit_adjusted = (adjusted >> (shift-1)) & 1; 2619 2620 T result = (sign << sign_offset) | 2621 (exponent << exponent_offset) | 2622 ((mantissa >> shift) << mantissa_offset); 2623 2624 // A very large mantissa can overflow during rounding. If this happens, the 2625 // exponent should be incremented and the mantissa set to 1.0 (encoded as 2626 // 0). Applying halfbit_adjusted after assembling the float has the nice 2627 // side-effect that this case is handled for free. 2628 // 2629 // This also handles cases where a very large finite value overflows to 2630 // infinity, or where a very large subnormal value overflows to become 2631 // normal. 2632 return result + halfbit_adjusted; 2633 } else { 2634 // We have to shift the mantissa to the left (or not at all). The input 2635 // mantissa is exactly representable in the output mantissa, so apply no 2636 // rounding correction. 2637 return (sign << sign_offset) | 2638 (exponent << exponent_offset) | 2639 ((mantissa << -shift) << mantissa_offset); 2640 } 2641 } 2642 2643 2644 // See FPRound for a description of this function. 2645 static inline double FPRoundToDouble(int64_t sign, int64_t exponent, 2646 uint64_t mantissa, FPRounding round_mode) { 2647 int64_t bits = 2648 FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign, 2649 exponent, 2650 mantissa, 2651 round_mode); 2652 return rawbits_to_double(bits); 2653 } 2654 2655 2656 // See FPRound for a description of this function. 2657 static inline float FPRoundToFloat(int64_t sign, int64_t exponent, 2658 uint64_t mantissa, FPRounding round_mode) { 2659 int32_t bits = 2660 FPRound<int32_t, kFloatExponentBits, kFloatMantissaBits>(sign, 2661 exponent, 2662 mantissa, 2663 round_mode); 2664 return rawbits_to_float(bits); 2665 } 2666 2667 2668 double Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) { 2669 if (src >= 0) { 2670 return UFixedToDouble(src, fbits, round); 2671 } else { 2672 // This works for all negative values, including INT64_MIN. 2673 return -UFixedToDouble(-src, fbits, round); 2674 } 2675 } 2676 2677 2678 double Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) { 2679 // An input of 0 is a special case because the result is effectively 2680 // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit. 2681 if (src == 0) { 2682 return 0.0; 2683 } 2684 2685 // Calculate the exponent. The highest significant bit will have the value 2686 // 2^exponent. 2687 const int highest_significant_bit = 63 - CountLeadingZeros(src, 64); 2688 const int64_t exponent = highest_significant_bit - fbits; 2689 2690 return FPRoundToDouble(0, exponent, src, round); 2691 } 2692 2693 2694 float Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) { 2695 if (src >= 0) { 2696 return UFixedToFloat(src, fbits, round); 2697 } else { 2698 // This works for all negative values, including INT64_MIN. 2699 return -UFixedToFloat(-src, fbits, round); 2700 } 2701 } 2702 2703 2704 float Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) { 2705 // An input of 0 is a special case because the result is effectively 2706 // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit. 2707 if (src == 0) { 2708 return 0.0f; 2709 } 2710 2711 // Calculate the exponent. The highest significant bit will have the value 2712 // 2^exponent. 2713 const int highest_significant_bit = 63 - CountLeadingZeros(src, 64); 2714 const int32_t exponent = highest_significant_bit - fbits; 2715 2716 return FPRoundToFloat(0, exponent, src, round); 2717 } 2718 2719 2720 double Simulator::FPRoundInt(double value, FPRounding round_mode) { 2721 if ((value == 0.0) || (value == kFP64PositiveInfinity) || 2722 (value == kFP64NegativeInfinity)) { 2723 return value; 2724 } else if (std::isnan(value)) { 2725 return FPProcessNaN(value); 2726 } 2727 2728 double int_result = floor(value); 2729 double error = value - int_result; 2730 switch (round_mode) { 2731 case FPTieAway: { 2732 // Take care of correctly handling the range ]-0.5, -0.0], which must 2733 // yield -0.0. 2734 if ((-0.5 < value) && (value < 0.0)) { 2735 int_result = -0.0; 2736 2737 } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) { 2738 // If the error is greater than 0.5, or is equal to 0.5 and the integer 2739 // result is positive, round up. 2740 int_result++; 2741 } 2742 break; 2743 } 2744 case FPTieEven: { 2745 // Take care of correctly handling the range [-0.5, -0.0], which must 2746 // yield -0.0. 2747 if ((-0.5 <= value) && (value < 0.0)) { 2748 int_result = -0.0; 2749 2750 // If the error is greater than 0.5, or is equal to 0.5 and the integer 2751 // result is odd, round up. 2752 } else if ((error > 0.5) || 2753 ((error == 0.5) && (fmod(int_result, 2) != 0))) { 2754 int_result++; 2755 } 2756 break; 2757 } 2758 case FPZero: { 2759 // If value > 0 then we take floor(value) 2760 // otherwise, ceil(value) 2761 if (value < 0) { 2762 int_result = ceil(value); 2763 } 2764 break; 2765 } 2766 case FPNegativeInfinity: { 2767 // We always use floor(value). 2768 break; 2769 } 2770 default: UNIMPLEMENTED(); 2771 } 2772 return int_result; 2773 } 2774 2775 2776 double Simulator::FPToDouble(float value) { 2777 switch (std::fpclassify(value)) { 2778 case FP_NAN: { 2779 if (fpcr().DN()) return kFP64DefaultNaN; 2780 2781 // Convert NaNs as the processor would: 2782 // - The sign is propagated. 2783 // - The payload (mantissa) is transferred entirely, except that the top 2784 // bit is forced to '1', making the result a quiet NaN. The unused 2785 // (low-order) payload bits are set to 0. 2786 uint32_t raw = float_to_rawbits(value); 2787 2788 uint64_t sign = raw >> 31; 2789 uint64_t exponent = (1 << 11) - 1; 2790 uint64_t payload = unsigned_bitextract_64(21, 0, raw); 2791 payload <<= (52 - 23); // The unused low-order bits should be 0. 2792 payload |= (1L << 51); // Force a quiet NaN. 2793 2794 return rawbits_to_double((sign << 63) | (exponent << 52) | payload); 2795 } 2796 2797 case FP_ZERO: 2798 case FP_NORMAL: 2799 case FP_SUBNORMAL: 2800 case FP_INFINITE: { 2801 // All other inputs are preserved in a standard cast, because every value 2802 // representable using an IEEE-754 float is also representable using an 2803 // IEEE-754 double. 2804 return static_cast<double>(value); 2805 } 2806 } 2807 2808 UNREACHABLE(); 2809 return static_cast<double>(value); 2810 } 2811 2812 2813 float Simulator::FPToFloat(double value, FPRounding round_mode) { 2814 // Only the FPTieEven rounding mode is implemented. 2815 DCHECK(round_mode == FPTieEven); 2816 USE(round_mode); 2817 2818 switch (std::fpclassify(value)) { 2819 case FP_NAN: { 2820 if (fpcr().DN()) return kFP32DefaultNaN; 2821 2822 // Convert NaNs as the processor would: 2823 // - The sign is propagated. 2824 // - The payload (mantissa) is transferred as much as possible, except 2825 // that the top bit is forced to '1', making the result a quiet NaN. 2826 uint64_t raw = double_to_rawbits(value); 2827 2828 uint32_t sign = raw >> 63; 2829 uint32_t exponent = (1 << 8) - 1; 2830 uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw); 2831 payload |= (1 << 22); // Force a quiet NaN. 2832 2833 return rawbits_to_float((sign << 31) | (exponent << 23) | payload); 2834 } 2835 2836 case FP_ZERO: 2837 case FP_INFINITE: { 2838 // In a C++ cast, any value representable in the target type will be 2839 // unchanged. This is always the case for +/-0.0 and infinities. 2840 return static_cast<float>(value); 2841 } 2842 2843 case FP_NORMAL: 2844 case FP_SUBNORMAL: { 2845 // Convert double-to-float as the processor would, assuming that FPCR.FZ 2846 // (flush-to-zero) is not set. 2847 uint64_t raw = double_to_rawbits(value); 2848 // Extract the IEEE-754 double components. 2849 uint32_t sign = raw >> 63; 2850 // Extract the exponent and remove the IEEE-754 encoding bias. 2851 int32_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023; 2852 // Extract the mantissa and add the implicit '1' bit. 2853 uint64_t mantissa = unsigned_bitextract_64(51, 0, raw); 2854 if (std::fpclassify(value) == FP_NORMAL) { 2855 mantissa |= (1UL << 52); 2856 } 2857 return FPRoundToFloat(sign, exponent, mantissa, round_mode); 2858 } 2859 } 2860 2861 UNREACHABLE(); 2862 return value; 2863 } 2864 2865 2866 void Simulator::VisitFPDataProcessing2Source(Instruction* instr) { 2867 AssertSupportedFPCR(); 2868 2869 unsigned fd = instr->Rd(); 2870 unsigned fn = instr->Rn(); 2871 unsigned fm = instr->Rm(); 2872 2873 // Fmaxnm and Fminnm have special NaN handling. 2874 switch (instr->Mask(FPDataProcessing2SourceMask)) { 2875 case FMAXNM_s: set_sreg(fd, FPMaxNM(sreg(fn), sreg(fm))); return; 2876 case FMAXNM_d: set_dreg(fd, FPMaxNM(dreg(fn), dreg(fm))); return; 2877 case FMINNM_s: set_sreg(fd, FPMinNM(sreg(fn), sreg(fm))); return; 2878 case FMINNM_d: set_dreg(fd, FPMinNM(dreg(fn), dreg(fm))); return; 2879 default: 2880 break; // Fall through. 2881 } 2882 2883 if (FPProcessNaNs(instr)) return; 2884 2885 switch (instr->Mask(FPDataProcessing2SourceMask)) { 2886 case FADD_s: set_sreg(fd, FPAdd(sreg(fn), sreg(fm))); break; 2887 case FADD_d: set_dreg(fd, FPAdd(dreg(fn), dreg(fm))); break; 2888 case FSUB_s: set_sreg(fd, FPSub(sreg(fn), sreg(fm))); break; 2889 case FSUB_d: set_dreg(fd, FPSub(dreg(fn), dreg(fm))); break; 2890 case FMUL_s: set_sreg(fd, FPMul(sreg(fn), sreg(fm))); break; 2891 case FMUL_d: set_dreg(fd, FPMul(dreg(fn), dreg(fm))); break; 2892 case FDIV_s: set_sreg(fd, FPDiv(sreg(fn), sreg(fm))); break; 2893 case FDIV_d: set_dreg(fd, FPDiv(dreg(fn), dreg(fm))); break; 2894 case FMAX_s: set_sreg(fd, FPMax(sreg(fn), sreg(fm))); break; 2895 case FMAX_d: set_dreg(fd, FPMax(dreg(fn), dreg(fm))); break; 2896 case FMIN_s: set_sreg(fd, FPMin(sreg(fn), sreg(fm))); break; 2897 case FMIN_d: set_dreg(fd, FPMin(dreg(fn), dreg(fm))); break; 2898 case FMAXNM_s: 2899 case FMAXNM_d: 2900 case FMINNM_s: 2901 case FMINNM_d: 2902 // These were handled before the standard FPProcessNaNs() stage. 2903 UNREACHABLE(); 2904 default: UNIMPLEMENTED(); 2905 } 2906 } 2907 2908 2909 void Simulator::VisitFPDataProcessing3Source(Instruction* instr) { 2910 AssertSupportedFPCR(); 2911 2912 unsigned fd = instr->Rd(); 2913 unsigned fn = instr->Rn(); 2914 unsigned fm = instr->Rm(); 2915 unsigned fa = instr->Ra(); 2916 2917 switch (instr->Mask(FPDataProcessing3SourceMask)) { 2918 // fd = fa +/- (fn * fm) 2919 case FMADD_s: set_sreg(fd, FPMulAdd(sreg(fa), sreg(fn), sreg(fm))); break; 2920 case FMSUB_s: set_sreg(fd, FPMulAdd(sreg(fa), -sreg(fn), sreg(fm))); break; 2921 case FMADD_d: set_dreg(fd, FPMulAdd(dreg(fa), dreg(fn), dreg(fm))); break; 2922 case FMSUB_d: set_dreg(fd, FPMulAdd(dreg(fa), -dreg(fn), dreg(fm))); break; 2923 // Negated variants of the above. 2924 case FNMADD_s: 2925 set_sreg(fd, FPMulAdd(-sreg(fa), -sreg(fn), sreg(fm))); 2926 break; 2927 case FNMSUB_s: 2928 set_sreg(fd, FPMulAdd(-sreg(fa), sreg(fn), sreg(fm))); 2929 break; 2930 case FNMADD_d: 2931 set_dreg(fd, FPMulAdd(-dreg(fa), -dreg(fn), dreg(fm))); 2932 break; 2933 case FNMSUB_d: 2934 set_dreg(fd, FPMulAdd(-dreg(fa), dreg(fn), dreg(fm))); 2935 break; 2936 default: UNIMPLEMENTED(); 2937 } 2938 } 2939 2940 2941 template <typename T> 2942 T Simulator::FPAdd(T op1, T op2) { 2943 // NaNs should be handled elsewhere. 2944 DCHECK(!std::isnan(op1) && !std::isnan(op2)); 2945 2946 if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) { 2947 // inf + -inf returns the default NaN. 2948 return FPDefaultNaN<T>(); 2949 } else { 2950 // Other cases should be handled by standard arithmetic. 2951 return op1 + op2; 2952 } 2953 } 2954 2955 2956 template <typename T> 2957 T Simulator::FPDiv(T op1, T op2) { 2958 // NaNs should be handled elsewhere. 2959 DCHECK(!std::isnan(op1) && !std::isnan(op2)); 2960 2961 if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) { 2962 // inf / inf and 0.0 / 0.0 return the default NaN. 2963 return FPDefaultNaN<T>(); 2964 } else { 2965 // Other cases should be handled by standard arithmetic. 2966 return op1 / op2; 2967 } 2968 } 2969 2970 2971 template <typename T> 2972 T Simulator::FPMax(T a, T b) { 2973 // NaNs should be handled elsewhere. 2974 DCHECK(!std::isnan(a) && !std::isnan(b)); 2975 2976 if ((a == 0.0) && (b == 0.0) && 2977 (copysign(1.0, a) != copysign(1.0, b))) { 2978 // a and b are zero, and the sign differs: return +0.0. 2979 return 0.0; 2980 } else { 2981 return (a > b) ? a : b; 2982 } 2983 } 2984 2985 2986 template <typename T> 2987 T Simulator::FPMaxNM(T a, T b) { 2988 if (IsQuietNaN(a) && !IsQuietNaN(b)) { 2989 a = kFP64NegativeInfinity; 2990 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) { 2991 b = kFP64NegativeInfinity; 2992 } 2993 2994 T result = FPProcessNaNs(a, b); 2995 return std::isnan(result) ? result : FPMax(a, b); 2996 } 2997 2998 template <typename T> 2999 T Simulator::FPMin(T a, T b) { 3000 // NaNs should be handled elsewhere. 3001 DCHECK(!std::isnan(a) && !std::isnan(b)); 3002 3003 if ((a == 0.0) && (b == 0.0) && 3004 (copysign(1.0, a) != copysign(1.0, b))) { 3005 // a and b are zero, and the sign differs: return -0.0. 3006 return -0.0; 3007 } else { 3008 return (a < b) ? a : b; 3009 } 3010 } 3011 3012 3013 template <typename T> 3014 T Simulator::FPMinNM(T a, T b) { 3015 if (IsQuietNaN(a) && !IsQuietNaN(b)) { 3016 a = kFP64PositiveInfinity; 3017 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) { 3018 b = kFP64PositiveInfinity; 3019 } 3020 3021 T result = FPProcessNaNs(a, b); 3022 return std::isnan(result) ? result : FPMin(a, b); 3023 } 3024 3025 3026 template <typename T> 3027 T Simulator::FPMul(T op1, T op2) { 3028 // NaNs should be handled elsewhere. 3029 DCHECK(!std::isnan(op1) && !std::isnan(op2)); 3030 3031 if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) { 3032 // inf * 0.0 returns the default NaN. 3033 return FPDefaultNaN<T>(); 3034 } else { 3035 // Other cases should be handled by standard arithmetic. 3036 return op1 * op2; 3037 } 3038 } 3039 3040 3041 template<typename T> 3042 T Simulator::FPMulAdd(T a, T op1, T op2) { 3043 T result = FPProcessNaNs3(a, op1, op2); 3044 3045 T sign_a = copysign(1.0, a); 3046 T sign_prod = copysign(1.0, op1) * copysign(1.0, op2); 3047 bool isinf_prod = std::isinf(op1) || std::isinf(op2); 3048 bool operation_generates_nan = 3049 (std::isinf(op1) && (op2 == 0.0)) || // inf * 0.0 3050 (std::isinf(op2) && (op1 == 0.0)) || // 0.0 * inf 3051 (std::isinf(a) && isinf_prod && (sign_a != sign_prod)); // inf - inf 3052 3053 if (std::isnan(result)) { 3054 // Generated NaNs override quiet NaNs propagated from a. 3055 if (operation_generates_nan && IsQuietNaN(a)) { 3056 return FPDefaultNaN<T>(); 3057 } else { 3058 return result; 3059 } 3060 } 3061 3062 // If the operation would produce a NaN, return the default NaN. 3063 if (operation_generates_nan) { 3064 return FPDefaultNaN<T>(); 3065 } 3066 3067 // Work around broken fma implementations for exact zero results: The sign of 3068 // exact 0.0 results is positive unless both a and op1 * op2 are negative. 3069 if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) { 3070 return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0; 3071 } 3072 3073 result = FusedMultiplyAdd(op1, op2, a); 3074 DCHECK(!std::isnan(result)); 3075 3076 // Work around broken fma implementations for rounded zero results: If a is 3077 // 0.0, the sign of the result is the sign of op1 * op2 before rounding. 3078 if ((a == 0.0) && (result == 0.0)) { 3079 return copysign(0.0, sign_prod); 3080 } 3081 3082 return result; 3083 } 3084 3085 3086 template <typename T> 3087 T Simulator::FPSqrt(T op) { 3088 if (std::isnan(op)) { 3089 return FPProcessNaN(op); 3090 } else if (op < 0.0) { 3091 return FPDefaultNaN<T>(); 3092 } else { 3093 return std::sqrt(op); 3094 } 3095 } 3096 3097 3098 template <typename T> 3099 T Simulator::FPSub(T op1, T op2) { 3100 // NaNs should be handled elsewhere. 3101 DCHECK(!std::isnan(op1) && !std::isnan(op2)); 3102 3103 if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) { 3104 // inf - inf returns the default NaN. 3105 return FPDefaultNaN<T>(); 3106 } else { 3107 // Other cases should be handled by standard arithmetic. 3108 return op1 - op2; 3109 } 3110 } 3111 3112 3113 template <typename T> 3114 T Simulator::FPProcessNaN(T op) { 3115 DCHECK(std::isnan(op)); 3116 return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op); 3117 } 3118 3119 3120 template <typename T> 3121 T Simulator::FPProcessNaNs(T op1, T op2) { 3122 if (IsSignallingNaN(op1)) { 3123 return FPProcessNaN(op1); 3124 } else if (IsSignallingNaN(op2)) { 3125 return FPProcessNaN(op2); 3126 } else if (std::isnan(op1)) { 3127 DCHECK(IsQuietNaN(op1)); 3128 return FPProcessNaN(op1); 3129 } else if (std::isnan(op2)) { 3130 DCHECK(IsQuietNaN(op2)); 3131 return FPProcessNaN(op2); 3132 } else { 3133 return 0.0; 3134 } 3135 } 3136 3137 3138 template <typename T> 3139 T Simulator::FPProcessNaNs3(T op1, T op2, T op3) { 3140 if (IsSignallingNaN(op1)) { 3141 return FPProcessNaN(op1); 3142 } else if (IsSignallingNaN(op2)) { 3143 return FPProcessNaN(op2); 3144 } else if (IsSignallingNaN(op3)) { 3145 return FPProcessNaN(op3); 3146 } else if (std::isnan(op1)) { 3147 DCHECK(IsQuietNaN(op1)); 3148 return FPProcessNaN(op1); 3149 } else if (std::isnan(op2)) { 3150 DCHECK(IsQuietNaN(op2)); 3151 return FPProcessNaN(op2); 3152 } else if (std::isnan(op3)) { 3153 DCHECK(IsQuietNaN(op3)); 3154 return FPProcessNaN(op3); 3155 } else { 3156 return 0.0; 3157 } 3158 } 3159 3160 3161 bool Simulator::FPProcessNaNs(Instruction* instr) { 3162 unsigned fd = instr->Rd(); 3163 unsigned fn = instr->Rn(); 3164 unsigned fm = instr->Rm(); 3165 bool done = false; 3166 3167 if (instr->Mask(FP64) == FP64) { 3168 double result = FPProcessNaNs(dreg(fn), dreg(fm)); 3169 if (std::isnan(result)) { 3170 set_dreg(fd, result); 3171 done = true; 3172 } 3173 } else { 3174 float result = FPProcessNaNs(sreg(fn), sreg(fm)); 3175 if (std::isnan(result)) { 3176 set_sreg(fd, result); 3177 done = true; 3178 } 3179 } 3180 3181 return done; 3182 } 3183 3184 3185 void Simulator::VisitSystem(Instruction* instr) { 3186 // Some system instructions hijack their Op and Cp fields to represent a 3187 // range of immediates instead of indicating a different instruction. This 3188 // makes the decoding tricky. 3189 if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) { 3190 switch (instr->Mask(SystemSysRegMask)) { 3191 case MRS: { 3192 switch (instr->ImmSystemRegister()) { 3193 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break; 3194 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break; 3195 default: UNIMPLEMENTED(); 3196 } 3197 break; 3198 } 3199 case MSR: { 3200 switch (instr->ImmSystemRegister()) { 3201 case NZCV: 3202 nzcv().SetRawValue(xreg(instr->Rt())); 3203 LogSystemRegister(NZCV); 3204 break; 3205 case FPCR: 3206 fpcr().SetRawValue(xreg(instr->Rt())); 3207 LogSystemRegister(FPCR); 3208 break; 3209 default: UNIMPLEMENTED(); 3210 } 3211 break; 3212 } 3213 } 3214 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 3215 DCHECK(instr->Mask(SystemHintMask) == HINT); 3216 switch (instr->ImmHint()) { 3217 case NOP: break; 3218 default: UNIMPLEMENTED(); 3219 } 3220 } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) { 3221 __sync_synchronize(); 3222 } else { 3223 UNIMPLEMENTED(); 3224 } 3225 } 3226 3227 3228 bool Simulator::GetValue(const char* desc, int64_t* value) { 3229 int regnum = CodeFromName(desc); 3230 if (regnum >= 0) { 3231 unsigned code = regnum; 3232 if (code == kZeroRegCode) { 3233 // Catch the zero register and return 0. 3234 *value = 0; 3235 return true; 3236 } else if (code == kSPRegInternalCode) { 3237 // Translate the stack pointer code to 31, for Reg31IsStackPointer. 3238 code = 31; 3239 } 3240 if (desc[0] == 'w') { 3241 *value = wreg(code, Reg31IsStackPointer); 3242 } else { 3243 *value = xreg(code, Reg31IsStackPointer); 3244 } 3245 return true; 3246 } else if (strncmp(desc, "0x", 2) == 0) { 3247 return SScanF(desc + 2, "%" SCNx64, 3248 reinterpret_cast<uint64_t*>(value)) == 1; 3249 } else { 3250 return SScanF(desc, "%" SCNu64, 3251 reinterpret_cast<uint64_t*>(value)) == 1; 3252 } 3253 } 3254 3255 3256 bool Simulator::PrintValue(const char* desc) { 3257 if (strcmp(desc, "csp") == 0) { 3258 DCHECK(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode)); 3259 PrintF(stream_, "%s csp:%s 0x%016" PRIx64 "%s\n", 3260 clr_reg_name, clr_reg_value, xreg(31, Reg31IsStackPointer), clr_normal); 3261 return true; 3262 } else if (strcmp(desc, "wcsp") == 0) { 3263 DCHECK(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode)); 3264 PrintF(stream_, "%s wcsp:%s 0x%08" PRIx32 "%s\n", 3265 clr_reg_name, clr_reg_value, wreg(31, Reg31IsStackPointer), clr_normal); 3266 return true; 3267 } 3268 3269 int i = CodeFromName(desc); 3270 STATIC_ASSERT(kNumberOfRegisters == kNumberOfFPRegisters); 3271 if (i < 0 || static_cast<unsigned>(i) >= kNumberOfFPRegisters) return false; 3272 3273 if (desc[0] == 'v') { 3274 PrintF(stream_, "%s %s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n", 3275 clr_fpreg_name, VRegNameForCode(i), 3276 clr_fpreg_value, double_to_rawbits(dreg(i)), 3277 clr_normal, 3278 clr_fpreg_name, DRegNameForCode(i), 3279 clr_fpreg_value, dreg(i), 3280 clr_fpreg_name, SRegNameForCode(i), 3281 clr_fpreg_value, sreg(i), 3282 clr_normal); 3283 return true; 3284 } else if (desc[0] == 'd') { 3285 PrintF(stream_, "%s %s:%s %g%s\n", 3286 clr_fpreg_name, DRegNameForCode(i), 3287 clr_fpreg_value, dreg(i), 3288 clr_normal); 3289 return true; 3290 } else if (desc[0] == 's') { 3291 PrintF(stream_, "%s %s:%s %g%s\n", 3292 clr_fpreg_name, SRegNameForCode(i), 3293 clr_fpreg_value, sreg(i), 3294 clr_normal); 3295 return true; 3296 } else if (desc[0] == 'w') { 3297 PrintF(stream_, "%s %s:%s 0x%08" PRIx32 "%s\n", 3298 clr_reg_name, WRegNameForCode(i), clr_reg_value, wreg(i), clr_normal); 3299 return true; 3300 } else { 3301 // X register names have a wide variety of starting characters, but anything 3302 // else will be an X register. 3303 PrintF(stream_, "%s %s:%s 0x%016" PRIx64 "%s\n", 3304 clr_reg_name, XRegNameForCode(i), clr_reg_value, xreg(i), clr_normal); 3305 return true; 3306 } 3307 } 3308 3309 3310 void Simulator::Debug() { 3311 #define COMMAND_SIZE 63 3312 #define ARG_SIZE 255 3313 3314 #define STR(a) #a 3315 #define XSTR(a) STR(a) 3316 3317 char cmd[COMMAND_SIZE + 1]; 3318 char arg1[ARG_SIZE + 1]; 3319 char arg2[ARG_SIZE + 1]; 3320 char* argv[3] = { cmd, arg1, arg2 }; 3321 3322 // Make sure to have a proper terminating character if reaching the limit. 3323 cmd[COMMAND_SIZE] = 0; 3324 arg1[ARG_SIZE] = 0; 3325 arg2[ARG_SIZE] = 0; 3326 3327 bool done = false; 3328 bool cleared_log_disasm_bit = false; 3329 3330 while (!done) { 3331 // Disassemble the next instruction to execute before doing anything else. 3332 PrintInstructionsAt(pc_, 1); 3333 // Read the command line. 3334 char* line = ReadLine("sim> "); 3335 if (line == NULL) { 3336 break; 3337 } else { 3338 // Repeat last command by default. 3339 char* last_input = last_debugger_input(); 3340 if (strcmp(line, "\n") == 0 && (last_input != NULL)) { 3341 DeleteArray(line); 3342 line = last_input; 3343 } else { 3344 // Update the latest command ran 3345 set_last_debugger_input(line); 3346 } 3347 3348 // Use sscanf to parse the individual parts of the command line. At the 3349 // moment no command expects more than two parameters. 3350 int argc = SScanF(line, 3351 "%" XSTR(COMMAND_SIZE) "s " 3352 "%" XSTR(ARG_SIZE) "s " 3353 "%" XSTR(ARG_SIZE) "s", 3354 cmd, arg1, arg2); 3355 3356 // stepi / si ------------------------------------------------------------ 3357 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 3358 // We are about to execute instructions, after which by default we 3359 // should increment the pc_. If it was set when reaching this debug 3360 // instruction, it has not been cleared because this instruction has not 3361 // completed yet. So clear it manually. 3362 pc_modified_ = false; 3363 3364 if (argc == 1) { 3365 ExecuteInstruction(); 3366 } else { 3367 int64_t number_of_instructions_to_execute = 1; 3368 GetValue(arg1, &number_of_instructions_to_execute); 3369 3370 set_log_parameters(log_parameters() | LOG_DISASM); 3371 while (number_of_instructions_to_execute-- > 0) { 3372 ExecuteInstruction(); 3373 } 3374 set_log_parameters(log_parameters() & ~LOG_DISASM); 3375 PrintF("\n"); 3376 } 3377 3378 // If it was necessary, the pc has already been updated or incremented 3379 // when executing the instruction. So we do not want it to be updated 3380 // again. It will be cleared when exiting. 3381 pc_modified_ = true; 3382 3383 // next / n -------------------------------------------------------------- 3384 } else if ((strcmp(cmd, "next") == 0) || (strcmp(cmd, "n") == 0)) { 3385 // Tell the simulator to break after the next executed BL. 3386 break_on_next_ = true; 3387 // Continue. 3388 done = true; 3389 3390 // continue / cont / c --------------------------------------------------- 3391 } else if ((strcmp(cmd, "continue") == 0) || 3392 (strcmp(cmd, "cont") == 0) || 3393 (strcmp(cmd, "c") == 0)) { 3394 // Leave the debugger shell. 3395 done = true; 3396 3397 // disassemble / disasm / di --------------------------------------------- 3398 } else if (strcmp(cmd, "disassemble") == 0 || 3399 strcmp(cmd, "disasm") == 0 || 3400 strcmp(cmd, "di") == 0) { 3401 int64_t n_of_instrs_to_disasm = 10; // default value. 3402 int64_t address = reinterpret_cast<int64_t>(pc_); // default value. 3403 if (argc >= 2) { // disasm <n of instrs> 3404 GetValue(arg1, &n_of_instrs_to_disasm); 3405 } 3406 if (argc >= 3) { // disasm <n of instrs> <address> 3407 GetValue(arg2, &address); 3408 } 3409 3410 // Disassemble. 3411 PrintInstructionsAt(reinterpret_cast<Instruction*>(address), 3412 n_of_instrs_to_disasm); 3413 PrintF("\n"); 3414 3415 // print / p ------------------------------------------------------------- 3416 } else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) { 3417 if (argc == 2) { 3418 if (strcmp(arg1, "all") == 0) { 3419 PrintRegisters(); 3420 PrintFPRegisters(); 3421 } else { 3422 if (!PrintValue(arg1)) { 3423 PrintF("%s unrecognized\n", arg1); 3424 } 3425 } 3426 } else { 3427 PrintF( 3428 "print <register>\n" 3429 " Print the content of a register. (alias 'p')\n" 3430 " 'print all' will print all registers.\n" 3431 " Use 'printobject' to get more details about the value.\n"); 3432 } 3433 3434 // printobject / po ------------------------------------------------------ 3435 } else if ((strcmp(cmd, "printobject") == 0) || 3436 (strcmp(cmd, "po") == 0)) { 3437 if (argc == 2) { 3438 int64_t value; 3439 OFStream os(stdout); 3440 if (GetValue(arg1, &value)) { 3441 Object* obj = reinterpret_cast<Object*>(value); 3442 os << arg1 << ": \n"; 3443 #ifdef DEBUG 3444 obj->Print(os); 3445 os << "\n"; 3446 #else 3447 os << Brief(obj) << "\n"; 3448 #endif 3449 } else { 3450 os << arg1 << " unrecognized\n"; 3451 } 3452 } else { 3453 PrintF("printobject <value>\n" 3454 "printobject <register>\n" 3455 " Print details about the value. (alias 'po')\n"); 3456 } 3457 3458 // stack / mem ---------------------------------------------------------- 3459 } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) { 3460 int64_t* cur = NULL; 3461 int64_t* end = NULL; 3462 int next_arg = 1; 3463 3464 if (strcmp(cmd, "stack") == 0) { 3465 cur = reinterpret_cast<int64_t*>(jssp()); 3466 3467 } else { // "mem" 3468 int64_t value; 3469 if (!GetValue(arg1, &value)) { 3470 PrintF("%s unrecognized\n", arg1); 3471 continue; 3472 } 3473 cur = reinterpret_cast<int64_t*>(value); 3474 next_arg++; 3475 } 3476 3477 int64_t words = 0; 3478 if (argc == next_arg) { 3479 words = 10; 3480 } else if (argc == next_arg + 1) { 3481 if (!GetValue(argv[next_arg], &words)) { 3482 PrintF("%s unrecognized\n", argv[next_arg]); 3483 PrintF("Printing 10 double words by default"); 3484 words = 10; 3485 } 3486 } else { 3487 UNREACHABLE(); 3488 } 3489 end = cur + words; 3490 3491 while (cur < end) { 3492 PrintF(" 0x%016" PRIx64 ": 0x%016" PRIx64 " %10" PRId64, 3493 reinterpret_cast<uint64_t>(cur), *cur, *cur); 3494 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); 3495 int64_t value = *cur; 3496 Heap* current_heap = v8::internal::Isolate::Current()->heap(); 3497 if (((value & 1) == 0) || current_heap->Contains(obj)) { 3498 PrintF(" ("); 3499 if ((value & kSmiTagMask) == 0) { 3500 STATIC_ASSERT(kSmiValueSize == 32); 3501 int32_t untagged = (value >> kSmiShift) & 0xffffffff; 3502 PrintF("smi %" PRId32, untagged); 3503 } else { 3504 obj->ShortPrint(); 3505 } 3506 PrintF(")"); 3507 } 3508 PrintF("\n"); 3509 cur++; 3510 } 3511 3512 // trace / t ------------------------------------------------------------- 3513 } else if (strcmp(cmd, "trace") == 0 || strcmp(cmd, "t") == 0) { 3514 if ((log_parameters() & (LOG_DISASM | LOG_REGS)) != 3515 (LOG_DISASM | LOG_REGS)) { 3516 PrintF("Enabling disassembly and registers tracing\n"); 3517 set_log_parameters(log_parameters() | LOG_DISASM | LOG_REGS); 3518 } else { 3519 PrintF("Disabling disassembly and registers tracing\n"); 3520 set_log_parameters(log_parameters() & ~(LOG_DISASM | LOG_REGS)); 3521 } 3522 3523 // break / b ------------------------------------------------------------- 3524 } else if (strcmp(cmd, "break") == 0 || strcmp(cmd, "b") == 0) { 3525 if (argc == 2) { 3526 int64_t value; 3527 if (GetValue(arg1, &value)) { 3528 SetBreakpoint(reinterpret_cast<Instruction*>(value)); 3529 } else { 3530 PrintF("%s unrecognized\n", arg1); 3531 } 3532 } else { 3533 ListBreakpoints(); 3534 PrintF("Use `break <address>` to set or disable a breakpoint\n"); 3535 } 3536 3537 // gdb ------------------------------------------------------------------- 3538 } else if (strcmp(cmd, "gdb") == 0) { 3539 PrintF("Relinquishing control to gdb.\n"); 3540 base::OS::DebugBreak(); 3541 PrintF("Regaining control from gdb.\n"); 3542 3543 // sysregs --------------------------------------------------------------- 3544 } else if (strcmp(cmd, "sysregs") == 0) { 3545 PrintSystemRegisters(); 3546 3547 // help / h -------------------------------------------------------------- 3548 } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "h") == 0) { 3549 PrintF( 3550 "stepi / si\n" 3551 " stepi <n>\n" 3552 " Step <n> instructions.\n" 3553 "next / n\n" 3554 " Continue execution until a BL instruction is reached.\n" 3555 " At this point a breakpoint is set just after this BL.\n" 3556 " Then execution is resumed. It will probably later hit the\n" 3557 " breakpoint just set.\n" 3558 "continue / cont / c\n" 3559 " Continue execution from here.\n" 3560 "disassemble / disasm / di\n" 3561 " disassemble <n> <address>\n" 3562 " Disassemble <n> instructions from current <address>.\n" 3563 " By default <n> is 20 and <address> is the current pc.\n" 3564 "print / p\n" 3565 " print <register>\n" 3566 " Print the content of a register.\n" 3567 " 'print all' will print all registers.\n" 3568 " Use 'printobject' to get more details about the value.\n" 3569 "printobject / po\n" 3570 " printobject <value>\n" 3571 " printobject <register>\n" 3572 " Print details about the value.\n" 3573 "stack\n" 3574 " stack [<words>]\n" 3575 " Dump stack content, default dump 10 words\n" 3576 "mem\n" 3577 " mem <address> [<words>]\n" 3578 " Dump memory content, default dump 10 words\n" 3579 "trace / t\n" 3580 " Toggle disassembly and register tracing\n" 3581 "break / b\n" 3582 " break : list all breakpoints\n" 3583 " break <address> : set / enable / disable a breakpoint.\n" 3584 "gdb\n" 3585 " Enter gdb.\n" 3586 "sysregs\n" 3587 " Print all system registers (including NZCV).\n"); 3588 } else { 3589 PrintF("Unknown command: %s\n", cmd); 3590 PrintF("Use 'help' for more information.\n"); 3591 } 3592 } 3593 if (cleared_log_disasm_bit == true) { 3594 set_log_parameters(log_parameters_ | LOG_DISASM); 3595 } 3596 } 3597 } 3598 3599 3600 void Simulator::VisitException(Instruction* instr) { 3601 switch (instr->Mask(ExceptionMask)) { 3602 case HLT: { 3603 if (instr->ImmException() == kImmExceptionIsDebug) { 3604 // Read the arguments encoded inline in the instruction stream. 3605 uint32_t code; 3606 uint32_t parameters; 3607 3608 memcpy(&code, 3609 pc_->InstructionAtOffset(kDebugCodeOffset), 3610 sizeof(code)); 3611 memcpy(¶meters, 3612 pc_->InstructionAtOffset(kDebugParamsOffset), 3613 sizeof(parameters)); 3614 char const *message = 3615 reinterpret_cast<char const*>( 3616 pc_->InstructionAtOffset(kDebugMessageOffset)); 3617 3618 // Always print something when we hit a debug point that breaks. 3619 // We are going to break, so printing something is not an issue in 3620 // terms of speed. 3621 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) { 3622 if (message != NULL) { 3623 PrintF(stream_, 3624 "# %sDebugger hit %d: %s%s%s\n", 3625 clr_debug_number, 3626 code, 3627 clr_debug_message, 3628 message, 3629 clr_normal); 3630 } else { 3631 PrintF(stream_, 3632 "# %sDebugger hit %d.%s\n", 3633 clr_debug_number, 3634 code, 3635 clr_normal); 3636 } 3637 } 3638 3639 // Other options. 3640 switch (parameters & kDebuggerTracingDirectivesMask) { 3641 case TRACE_ENABLE: 3642 set_log_parameters(log_parameters() | parameters); 3643 if (parameters & LOG_SYS_REGS) { PrintSystemRegisters(); } 3644 if (parameters & LOG_REGS) { PrintRegisters(); } 3645 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); } 3646 break; 3647 case TRACE_DISABLE: 3648 set_log_parameters(log_parameters() & ~parameters); 3649 break; 3650 case TRACE_OVERRIDE: 3651 set_log_parameters(parameters); 3652 break; 3653 default: 3654 // We don't support a one-shot LOG_DISASM. 3655 DCHECK((parameters & LOG_DISASM) == 0); 3656 // Don't print information that is already being traced. 3657 parameters &= ~log_parameters(); 3658 // Print the requested information. 3659 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(); 3660 if (parameters & LOG_REGS) PrintRegisters(); 3661 if (parameters & LOG_FP_REGS) PrintFPRegisters(); 3662 } 3663 3664 // The stop parameters are inlined in the code. Skip them: 3665 // - Skip to the end of the message string. 3666 size_t size = kDebugMessageOffset + strlen(message) + 1; 3667 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize)); 3668 // - Verify that the unreachable marker is present. 3669 DCHECK(pc_->Mask(ExceptionMask) == HLT); 3670 DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable); 3671 // - Skip past the unreachable marker. 3672 set_pc(pc_->following()); 3673 3674 // Check if the debugger should break. 3675 if (parameters & BREAK) Debug(); 3676 3677 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) { 3678 DoRuntimeCall(instr); 3679 } else if (instr->ImmException() == kImmExceptionIsPrintf) { 3680 DoPrintf(instr); 3681 3682 } else if (instr->ImmException() == kImmExceptionIsUnreachable) { 3683 fprintf(stream_, "Hit UNREACHABLE marker at PC=%p.\n", 3684 reinterpret_cast<void*>(pc_)); 3685 abort(); 3686 3687 } else { 3688 base::OS::DebugBreak(); 3689 } 3690 break; 3691 } 3692 3693 default: 3694 UNIMPLEMENTED(); 3695 } 3696 } 3697 3698 3699 void Simulator::DoPrintf(Instruction* instr) { 3700 DCHECK((instr->Mask(ExceptionMask) == HLT) && 3701 (instr->ImmException() == kImmExceptionIsPrintf)); 3702 3703 // Read the arguments encoded inline in the instruction stream. 3704 uint32_t arg_count; 3705 uint32_t arg_pattern_list; 3706 STATIC_ASSERT(sizeof(*instr) == 1); 3707 memcpy(&arg_count, 3708 instr + kPrintfArgCountOffset, 3709 sizeof(arg_count)); 3710 memcpy(&arg_pattern_list, 3711 instr + kPrintfArgPatternListOffset, 3712 sizeof(arg_pattern_list)); 3713 3714 DCHECK(arg_count <= kPrintfMaxArgCount); 3715 DCHECK((arg_pattern_list >> (kPrintfArgPatternBits * arg_count)) == 0); 3716 3717 // We need to call the host printf function with a set of arguments defined by 3718 // arg_pattern_list. Because we don't know the types and sizes of the 3719 // arguments, this is very difficult to do in a robust and portable way. To 3720 // work around the problem, we pick apart the format string, and print one 3721 // format placeholder at a time. 3722 3723 // Allocate space for the format string. We take a copy, so we can modify it. 3724 // Leave enough space for one extra character per expected argument (plus the 3725 // '\0' termination). 3726 const char * format_base = reg<const char *>(0); 3727 DCHECK(format_base != NULL); 3728 size_t length = strlen(format_base) + 1; 3729 char * const format = new char[length + arg_count]; 3730 3731 // A list of chunks, each with exactly one format placeholder. 3732 const char * chunks[kPrintfMaxArgCount]; 3733 3734 // Copy the format string and search for format placeholders. 3735 uint32_t placeholder_count = 0; 3736 char * format_scratch = format; 3737 for (size_t i = 0; i < length; i++) { 3738 if (format_base[i] != '%') { 3739 *format_scratch++ = format_base[i]; 3740 } else { 3741 if (format_base[i + 1] == '%') { 3742 // Ignore explicit "%%" sequences. 3743 *format_scratch++ = format_base[i]; 3744 3745 if (placeholder_count == 0) { 3746 // The first chunk is passed to printf using "%s", so we need to 3747 // unescape "%%" sequences in this chunk. (Just skip the next '%'.) 3748 i++; 3749 } else { 3750 // Otherwise, pass through "%%" unchanged. 3751 *format_scratch++ = format_base[++i]; 3752 } 3753 } else { 3754 CHECK(placeholder_count < arg_count); 3755 // Insert '\0' before placeholders, and store their locations. 3756 *format_scratch++ = '\0'; 3757 chunks[placeholder_count++] = format_scratch; 3758 *format_scratch++ = format_base[i]; 3759 } 3760 } 3761 } 3762 DCHECK(format_scratch <= (format + length + arg_count)); 3763 CHECK(placeholder_count == arg_count); 3764 3765 // Finally, call printf with each chunk, passing the appropriate register 3766 // argument. Normally, printf returns the number of bytes transmitted, so we 3767 // can emulate a single printf call by adding the result from each chunk. If 3768 // any call returns a negative (error) value, though, just return that value. 3769 3770 fprintf(stream_, "%s", clr_printf); 3771 3772 // Because '\0' is inserted before each placeholder, the first string in 3773 // 'format' contains no format placeholders and should be printed literally. 3774 int result = fprintf(stream_, "%s", format); 3775 int pcs_r = 1; // Start at x1. x0 holds the format string. 3776 int pcs_f = 0; // Start at d0. 3777 if (result >= 0) { 3778 for (uint32_t i = 0; i < placeholder_count; i++) { 3779 int part_result = -1; 3780 3781 uint32_t arg_pattern = arg_pattern_list >> (i * kPrintfArgPatternBits); 3782 arg_pattern &= (1 << kPrintfArgPatternBits) - 1; 3783 switch (arg_pattern) { 3784 case kPrintfArgW: 3785 part_result = fprintf(stream_, chunks[i], wreg(pcs_r++)); 3786 break; 3787 case kPrintfArgX: 3788 part_result = fprintf(stream_, chunks[i], xreg(pcs_r++)); 3789 break; 3790 case kPrintfArgD: 3791 part_result = fprintf(stream_, chunks[i], dreg(pcs_f++)); 3792 break; 3793 default: UNREACHABLE(); 3794 } 3795 3796 if (part_result < 0) { 3797 // Handle error values. 3798 result = part_result; 3799 break; 3800 } 3801 3802 result += part_result; 3803 } 3804 } 3805 3806 fprintf(stream_, "%s", clr_normal); 3807 3808 #ifdef DEBUG 3809 CorruptAllCallerSavedCPURegisters(); 3810 #endif 3811 3812 // Printf returns its result in x0 (just like the C library's printf). 3813 set_xreg(0, result); 3814 3815 // The printf parameters are inlined in the code, so skip them. 3816 set_pc(instr->InstructionAtOffset(kPrintfLength)); 3817 3818 // Set LR as if we'd just called a native printf function. 3819 set_lr(pc()); 3820 3821 delete[] format; 3822 } 3823 3824 3825 #endif // USE_SIMULATOR 3826 3827 } } // namespace v8::internal 3828 3829 #endif // V8_TARGET_ARCH_ARM64 3830