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