Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: src/arm64/simulator-arm64.cc

Issue 548473002: ARM64: Fix and improve --trace-sim register trace. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Reformat only. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <cmath> 6 #include <cmath>
7 #include <cstdarg> 7 #include <cstdarg>
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #if V8_TARGET_ARCH_ARM64 10 #if V8_TARGET_ARCH_ARM64
(...skipping 12 matching lines...) Expand all
23 23
24 24
25 // This macro provides a platform independent use of sscanf. The reason for 25 // This macro provides a platform independent use of sscanf. The reason for
26 // SScanF not being implemented in a platform independent way through 26 // SScanF not being implemented in a platform independent way through
27 // ::v8::internal::OS in the same way as SNPrintF is that the 27 // ::v8::internal::OS in the same way as SNPrintF is that the
28 // Windows C Run-Time Library does not provide vsscanf. 28 // Windows C Run-Time Library does not provide vsscanf.
29 #define SScanF sscanf // NOLINT 29 #define SScanF sscanf // NOLINT
30 30
31 31
32 // Helpers for colors. 32 // Helpers for colors.
33 // Depending on your terminal configuration, the colour names may not match the 33 #define COLOUR(colour_code) "\033[0;" colour_code "m"
34 // observed colours. 34 #define COLOUR_BOLD(colour_code) "\033[1;" colour_code "m"
35 #define COLOUR(colour_code) "\033[" colour_code "m" 35 #define NORMAL ""
36 #define BOLD(colour_code) "1;" colour_code 36 #define GREY "30"
37 #define NORMAL "" 37 #define RED "31"
38 #define GREY "30" 38 #define GREEN "32"
39 #define GREEN "32" 39 #define YELLOW "33"
40 #define ORANGE "33" 40 #define BLUE "34"
41 #define BLUE "34" 41 #define MAGENTA "35"
42 #define PURPLE "35" 42 #define CYAN "36"
43 #define INDIGO "36" 43 #define WHITE "37"
44 #define WHITE "37"
45 typedef char const * const TEXT_COLOUR; 44 typedef char const * const TEXT_COLOUR;
46 TEXT_COLOUR clr_normal = FLAG_log_colour ? COLOUR(NORMAL) : ""; 45 TEXT_COLOUR clr_normal = FLAG_log_colour ? COLOUR(NORMAL) : "";
47 TEXT_COLOUR clr_flag_name = FLAG_log_colour ? COLOUR(BOLD(GREY)) : ""; 46 TEXT_COLOUR clr_flag_name = FLAG_log_colour ? COLOUR_BOLD(WHITE) : "";
48 TEXT_COLOUR clr_flag_value = FLAG_log_colour ? COLOUR(BOLD(WHITE)) : ""; 47 TEXT_COLOUR clr_flag_value = FLAG_log_colour ? COLOUR(NORMAL) : "";
49 TEXT_COLOUR clr_reg_name = FLAG_log_colour ? COLOUR(BOLD(BLUE)) : ""; 48 TEXT_COLOUR clr_reg_name = FLAG_log_colour ? COLOUR_BOLD(CYAN) : "";
50 TEXT_COLOUR clr_reg_value = FLAG_log_colour ? COLOUR(BOLD(INDIGO)) : ""; 49 TEXT_COLOUR clr_reg_value = FLAG_log_colour ? COLOUR(CYAN) : "";
51 TEXT_COLOUR clr_fpreg_name = FLAG_log_colour ? COLOUR(BOLD(ORANGE)) : ""; 50 TEXT_COLOUR clr_fpreg_name = FLAG_log_colour ? COLOUR_BOLD(MAGENTA) : "";
52 TEXT_COLOUR clr_fpreg_value = FLAG_log_colour ? COLOUR(BOLD(PURPLE)) : ""; 51 TEXT_COLOUR clr_fpreg_value = FLAG_log_colour ? COLOUR(MAGENTA) : "";
53 TEXT_COLOUR clr_memory_value = FLAG_log_colour ? COLOUR(BOLD(GREEN)) : ""; 52 TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR_BOLD(BLUE) : "";
54 TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR(GREEN) : ""; 53 TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR_BOLD(YELLOW) : "";
55 TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR(BOLD(ORANGE)) : ""; 54 TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : "";
56 TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(ORANGE) : "";
57 TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : ""; 55 TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : "";
58 56
59 57
60 // This is basically the same as PrintF, with a guard for FLAG_trace_sim. 58 // This is basically the same as PrintF, with a guard for FLAG_trace_sim.
61 void Simulator::TraceSim(const char* format, ...) { 59 void Simulator::TraceSim(const char* format, ...) {
62 if (FLAG_trace_sim) { 60 if (FLAG_trace_sim) {
63 va_list arguments; 61 va_list arguments;
64 va_start(arguments, format); 62 va_start(arguments, format);
65 base::OS::VFPrint(stream_, format, arguments); 63 base::OS::VFPrint(stream_, format, arguments);
66 va_end(arguments); 64 va_end(arguments);
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 DCHECK(sizeof(uintptr_t) < 2 * kXRegSize); 328 DCHECK(sizeof(uintptr_t) < 2 * kXRegSize);
331 set_sp(current_sp + 2 * kXRegSize); 329 set_sp(current_sp + 2 * kXRegSize);
332 return address; 330 return address;
333 } 331 }
334 332
335 333
336 // Returns the limit of the stack area to enable checking for stack overflows. 334 // Returns the limit of the stack area to enable checking for stack overflows.
337 uintptr_t Simulator::StackLimit() const { 335 uintptr_t Simulator::StackLimit() const {
338 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when 336 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
339 // pushing values. 337 // pushing values.
340 return reinterpret_cast<uintptr_t>(stack_limit_) + 1024; 338 return stack_limit_ + 1024;
341 } 339 }
342 340
343 341
344 Simulator::Simulator(Decoder<DispatchingDecoderVisitor>* decoder, 342 Simulator::Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
345 Isolate* isolate, FILE* stream) 343 Isolate* isolate, FILE* stream)
346 : decoder_(decoder), 344 : decoder_(decoder),
347 last_debugger_input_(NULL), 345 last_debugger_input_(NULL),
348 log_parameters_(NO_PARAM), 346 log_parameters_(NO_PARAM),
349 isolate_(isolate) { 347 isolate_(isolate) {
350 // Setup the decoder. 348 // Setup the decoder.
(...skipping 22 matching lines...) Expand all
373 Init(stdout); 371 Init(stdout);
374 CHECK(!FLAG_trace_sim && !FLAG_log_instruction_stats); 372 CHECK(!FLAG_trace_sim && !FLAG_log_instruction_stats);
375 } 373 }
376 374
377 375
378 void Simulator::Init(FILE* stream) { 376 void Simulator::Init(FILE* stream) {
379 ResetState(); 377 ResetState();
380 378
381 // Allocate and setup the simulator stack. 379 // Allocate and setup the simulator stack.
382 stack_size_ = (FLAG_sim_stack_size * KB) + (2 * stack_protection_size_); 380 stack_size_ = (FLAG_sim_stack_size * KB) + (2 * stack_protection_size_);
383 stack_ = new byte[stack_size_]; 381 stack_ = reinterpret_cast<uintptr_t>(new byte[stack_size_]);
384 stack_limit_ = stack_ + stack_protection_size_; 382 stack_limit_ = stack_ + stack_protection_size_;
385 byte* tos = stack_ + stack_size_ - stack_protection_size_; 383 uintptr_t tos = stack_ + stack_size_ - stack_protection_size_;
386 // The stack pointer must be 16 bytes aligned. 384 // The stack pointer must be 16-byte aligned.
387 set_sp(reinterpret_cast<int64_t>(tos) & ~0xfUL); 385 set_sp(tos & ~0xfUL);
388 386
389 stream_ = stream; 387 stream_ = stream;
390 print_disasm_ = new PrintDisassembler(stream_); 388 print_disasm_ = new PrintDisassembler(stream_);
391 389
392 // The debugger needs to disassemble code without the simulator executing an 390 // The debugger needs to disassemble code without the simulator executing an
393 // instruction, so we create a dedicated decoder. 391 // instruction, so we create a dedicated decoder.
394 disassembler_decoder_ = new Decoder<DispatchingDecoderVisitor>(); 392 disassembler_decoder_ = new Decoder<DispatchingDecoderVisitor>();
395 disassembler_decoder_->AppendVisitor(print_disasm_); 393 disassembler_decoder_->AppendVisitor(print_disasm_);
396 } 394 }
397 395
(...skipping 15 matching lines...) Expand all
413 // Returning to address 0 exits the Simulator. 411 // Returning to address 0 exits the Simulator.
414 set_lr(kEndOfSimAddress); 412 set_lr(kEndOfSimAddress);
415 413
416 // Reset debug helpers. 414 // Reset debug helpers.
417 breakpoints_.empty(); 415 breakpoints_.empty();
418 break_on_next_= false; 416 break_on_next_= false;
419 } 417 }
420 418
421 419
422 Simulator::~Simulator() { 420 Simulator::~Simulator() {
423 delete[] stack_; 421 delete[] reinterpret_cast<byte*>(stack_);
424 if (FLAG_log_instruction_stats) { 422 if (FLAG_log_instruction_stats) {
425 delete instrument_; 423 delete instrument_;
426 } 424 }
427 delete disassembler_decoder_; 425 delete disassembler_decoder_;
428 delete print_disasm_; 426 delete print_disasm_;
429 DeleteArray(last_debugger_input_); 427 DeleteArray(last_debugger_input_);
430 delete decoder_; 428 delete decoder_;
431 } 429 }
432 430
433 431
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 725
728 726
729 void* Simulator::RedirectExternalReference(void* external_function, 727 void* Simulator::RedirectExternalReference(void* external_function,
730 ExternalReference::Type type) { 728 ExternalReference::Type type) {
731 Redirection* redirection = Redirection::Get(external_function, type); 729 Redirection* redirection = Redirection::Get(external_function, type);
732 return redirection->address_of_redirect_call(); 730 return redirection->address_of_redirect_call();
733 } 731 }
734 732
735 733
736 const char* Simulator::xreg_names[] = { 734 const char* Simulator::xreg_names[] = {
737 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", 735 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
738 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", 736 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
739 "ip0", "ip1", "x18", "x19", "x20", "x21", "x22", "x23", 737 "ip0", "ip1", "x18", "x19", "x20", "x21", "x22", "x23",
740 "x24", "x25", "x26", "cp", "jssp", "fp", "lr", "xzr", "csp"}; 738 "x24", "x25", "x26", "cp", "jssp", "fp", "lr", "xzr", "csp"};
741 739
742 const char* Simulator::wreg_names[] = { 740 const char* Simulator::wreg_names[] = {
743 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", 741 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
744 "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", 742 "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
745 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", 743 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
746 "w24", "w25", "w26", "wcp", "wjssp", "wfp", "wlr", "wzr", "wcsp"}; 744 "w24", "w25", "w26", "wcp", "wjssp", "wfp", "wlr", "wzr", "wcsp"};
747 745
748 const char* Simulator::sreg_names[] = { 746 const char* Simulator::sreg_names[] = {
749 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 747 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
750 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", 748 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
751 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", 749 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
752 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"}; 750 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"};
753 751
754 const char* Simulator::dreg_names[] = { 752 const char* Simulator::dreg_names[] = {
755 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 753 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
756 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", 754 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
757 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", 755 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
758 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"}; 756 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
759 757
760 const char* Simulator::vreg_names[] = { 758 const char* Simulator::vreg_names[] = {
761 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 759 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
762 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 760 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
763 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 761 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
764 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"}; 762 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
765 763
766 764
767 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) { 765 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) {
766 STATIC_ASSERT(arraysize(Simulator::wreg_names) == (kNumberOfRegisters + 1));
768 DCHECK(code < kNumberOfRegisters); 767 DCHECK(code < kNumberOfRegisters);
769 // If the code represents the stack pointer, index the name after zr. 768 // If the code represents the stack pointer, index the name after zr.
770 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 769 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
771 code = kZeroRegCode + 1; 770 code = kZeroRegCode + 1;
772 } 771 }
773 return wreg_names[code]; 772 // Using basic pointer arithmetic (instead of an array index) avoids an
773 // erroneous GCC warning about an out-of-bounds array index.
774 return *(wreg_names + code);
774 } 775 }
775 776
776 777
777 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) { 778 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) {
779 STATIC_ASSERT(arraysize(Simulator::xreg_names) == (kNumberOfRegisters + 1));
778 DCHECK(code < kNumberOfRegisters); 780 DCHECK(code < kNumberOfRegisters);
779 // If the code represents the stack pointer, index the name after zr. 781 // If the code represents the stack pointer, index the name after zr.
780 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 782 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
781 code = kZeroRegCode + 1; 783 code = kZeroRegCode + 1;
782 } 784 }
783 return xreg_names[code]; 785 return *(xreg_names + code);
784 } 786 }
785 787
786 788
787 const char* Simulator::SRegNameForCode(unsigned code) { 789 const char* Simulator::SRegNameForCode(unsigned code) {
790 STATIC_ASSERT(arraysize(Simulator::sreg_names) == kNumberOfFPRegisters);
788 DCHECK(code < kNumberOfFPRegisters); 791 DCHECK(code < kNumberOfFPRegisters);
789 return sreg_names[code]; 792 return *(sreg_names + code);
790 } 793 }
791 794
792 795
793 const char* Simulator::DRegNameForCode(unsigned code) { 796 const char* Simulator::DRegNameForCode(unsigned code) {
797 STATIC_ASSERT(arraysize(Simulator::dreg_names) == kNumberOfFPRegisters);
794 DCHECK(code < kNumberOfFPRegisters); 798 DCHECK(code < kNumberOfFPRegisters);
795 return dreg_names[code]; 799 return *(dreg_names + code);
796 } 800 }
797 801
798 802
799 const char* Simulator::VRegNameForCode(unsigned code) { 803 const char* Simulator::VRegNameForCode(unsigned code) {
804 STATIC_ASSERT(arraysize(Simulator::vreg_names) == kNumberOfFPRegisters);
800 DCHECK(code < kNumberOfFPRegisters); 805 DCHECK(code < kNumberOfFPRegisters);
801 return vreg_names[code]; 806 return *(vreg_names + code);
802 } 807 }
803 808
804 809
805 int Simulator::CodeFromName(const char* name) { 810 int Simulator::CodeFromName(const char* name) {
806 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 811 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
807 if ((strcmp(xreg_names[i], name) == 0) || 812 if ((strcmp(xreg_names[i], name) == 0) ||
808 (strcmp(wreg_names[i], name) == 0)) { 813 (strcmp(wreg_names[i], name) == 0)) {
809 return i; 814 return i;
810 } 815 }
811 } 816 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0); 853 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0);
849 854
850 N = CalcNFlag(result); 855 N = CalcNFlag(result);
851 Z = CalcZFlag(result); 856 Z = CalcZFlag(result);
852 857
853 if (set_flags) { 858 if (set_flags) {
854 nzcv().SetN(N); 859 nzcv().SetN(N);
855 nzcv().SetZ(Z); 860 nzcv().SetZ(Z);
856 nzcv().SetC(C); 861 nzcv().SetC(C);
857 nzcv().SetV(V); 862 nzcv().SetV(V);
863 LogSystemRegister(NZCV);
858 } 864 }
859 return result; 865 return result;
860 } 866 }
861 867
862 868
863 template<typename T> 869 template<typename T>
864 void Simulator::AddSubWithCarry(Instruction* instr) { 870 void Simulator::AddSubWithCarry(Instruction* instr) {
865 T op2 = reg<T>(instr->Rm()); 871 T op2 = reg<T>(instr->Rm());
866 T new_val; 872 T new_val;
867 873
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 nzcv().SetRawValue(FPUnorderedFlag); 977 nzcv().SetRawValue(FPUnorderedFlag);
972 } else if (val0 < val1) { 978 } else if (val0 < val1) {
973 nzcv().SetRawValue(FPLessThanFlag); 979 nzcv().SetRawValue(FPLessThanFlag);
974 } else if (val0 > val1) { 980 } else if (val0 > val1) {
975 nzcv().SetRawValue(FPGreaterThanFlag); 981 nzcv().SetRawValue(FPGreaterThanFlag);
976 } else if (val0 == val1) { 982 } else if (val0 == val1) {
977 nzcv().SetRawValue(FPEqualFlag); 983 nzcv().SetRawValue(FPEqualFlag);
978 } else { 984 } else {
979 UNREACHABLE(); 985 UNREACHABLE();
980 } 986 }
987 LogSystemRegister(NZCV);
981 } 988 }
982 989
983 990
984 void Simulator::SetBreakpoint(Instruction* location) { 991 void Simulator::SetBreakpoint(Instruction* location) {
985 for (unsigned i = 0; i < breakpoints_.size(); i++) { 992 for (unsigned i = 0; i < breakpoints_.size(); i++) {
986 if (breakpoints_.at(i).location == location) { 993 if (breakpoints_.at(i).location == location) {
987 PrintF(stream_, 994 PrintF(stream_,
988 "Existing breakpoint at %p was %s\n", 995 "Existing breakpoint at %p was %s\n",
989 reinterpret_cast<void*>(location), 996 reinterpret_cast<void*>(location),
990 breakpoints_.at(i).enabled ? "disabled" : "enabled"); 997 breakpoints_.at(i).enabled ? "disabled" : "enabled");
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 1044
1038 1045
1039 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) { 1046 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) {
1040 Instruction* end = start->InstructionAtOffset(count * kInstructionSize); 1047 Instruction* end = start->InstructionAtOffset(count * kInstructionSize);
1041 for (Instruction* pc = start; pc < end; pc = pc->following()) { 1048 for (Instruction* pc = start; pc < end; pc = pc->following()) {
1042 disassembler_decoder_->Decode(pc); 1049 disassembler_decoder_->Decode(pc);
1043 } 1050 }
1044 } 1051 }
1045 1052
1046 1053
1047 void Simulator::PrintSystemRegisters(bool print_all) { 1054 void Simulator::PrintSystemRegisters() {
1048 static bool first_run = true; 1055 PrintSystemRegister(NZCV);
1049 1056 PrintSystemRegister(FPCR);
1050 static SimSystemRegister last_nzcv; 1057 }
1051 if (print_all || first_run || (last_nzcv.RawValue() != nzcv().RawValue())) { 1058
1052 fprintf(stream_, "# %sFLAGS: %sN:%d Z:%d C:%d V:%d%s\n", 1059
1053 clr_flag_name, 1060 void Simulator::PrintRegisters() {
1054 clr_flag_value,
1055 nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(),
1056 clr_normal);
1057 }
1058 last_nzcv = nzcv();
1059
1060 static SimSystemRegister last_fpcr;
1061 if (print_all || first_run || (last_fpcr.RawValue() != fpcr().RawValue())) {
1062 static const char * rmode[] = {
1063 "0b00 (Round to Nearest)",
1064 "0b01 (Round towards Plus Infinity)",
1065 "0b10 (Round towards Minus Infinity)",
1066 "0b11 (Round towards Zero)"
1067 };
1068 DCHECK(fpcr().RMode() < arraysize(rmode));
1069 fprintf(stream_, "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n",
1070 clr_flag_name,
1071 clr_flag_value,
1072 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()],
1073 clr_normal);
1074 }
1075 last_fpcr = fpcr();
1076
1077 first_run = false;
1078 }
1079
1080
1081 void Simulator::PrintRegisters(bool print_all_regs) {
1082 static bool first_run = true;
1083 static int64_t last_regs[kNumberOfRegisters];
1084
1085 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 1061 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
1086 if (print_all_regs || first_run || 1062 PrintRegister(i);
1087 (last_regs[i] != xreg(i, Reg31IsStackPointer))) { 1063 }
1064 }
1065
1066
1067 void Simulator::PrintFPRegisters() {
1068 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
1069 PrintFPRegister(i);
1070 }
1071 }
1072
1073
1074 void Simulator::PrintRegister(unsigned code, Reg31Mode r31mode) {
1075 // Don't print writes into xzr.
1076 if ((code == kZeroRegCode) && (r31mode == Reg31IsZeroRegister)) {
1077 return;
1078 }
1079
1080 // The template is "# x<code>:value".
1081 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s\n",
1082 clr_reg_name, XRegNameForCode(code, r31mode),
1083 clr_reg_value, reg<uint64_t>(code, r31mode), clr_normal);
1084 }
1085
1086
1087 void Simulator::PrintFPRegister(unsigned code, PrintFPRegisterSizes sizes) {
1088 // The template is "# v<code>:bits (d<code>:value, ...)".
1089
1090 DCHECK(sizes != 0);
1091 DCHECK((sizes & kPrintAllFPRegValues) == sizes);
1092
1093 // Print the raw bits.
1094 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (",
1095 clr_fpreg_name, VRegNameForCode(code),
1096 clr_fpreg_value, fpreg<uint64_t>(code), clr_normal);
1097
1098 // Print all requested value interpretations.
1099 bool need_separator = false;
1100 if (sizes & kPrintDRegValue) {
1101 fprintf(stream_, "%s%s%s: %s%g%s",
1102 need_separator ? ", " : "",
1103 clr_fpreg_name, DRegNameForCode(code),
1104 clr_fpreg_value, fpreg<double>(code), clr_normal);
1105 need_separator = true;
1106 }
1107
1108 if (sizes & kPrintSRegValue) {
1109 fprintf(stream_, "%s%s%s: %s%g%s",
1110 need_separator ? ", " : "",
1111 clr_fpreg_name, SRegNameForCode(code),
1112 clr_fpreg_value, fpreg<float>(code), clr_normal);
1113 need_separator = true;
1114 }
1115
1116 // End the value list.
1117 fprintf(stream_, ")\n");
1118 }
1119
1120
1121 void Simulator::PrintSystemRegister(SystemRegister id) {
1122 switch (id) {
1123 case NZCV:
1124 fprintf(stream_, "# %sNZCV: %sN:%d Z:%d C:%d V:%d%s\n",
1125 clr_flag_name, clr_flag_value,
1126 nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(),
1127 clr_normal);
1128 break;
1129 case FPCR: {
1130 static const char * rmode[] = {
1131 "0b00 (Round to Nearest)",
1132 "0b01 (Round towards Plus Infinity)",
1133 "0b10 (Round towards Minus Infinity)",
1134 "0b11 (Round towards Zero)"
1135 };
1136 DCHECK(fpcr().RMode() < arraysize(rmode));
1088 fprintf(stream_, 1137 fprintf(stream_,
1089 "# %s%4s:%s 0x%016" PRIx64 "%s\n", 1138 "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n",
1090 clr_reg_name, 1139 clr_flag_name, clr_flag_value,
1091 XRegNameForCode(i, Reg31IsStackPointer), 1140 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()],
1092 clr_reg_value,
1093 xreg(i, Reg31IsStackPointer),
1094 clr_normal); 1141 clr_normal);
1142 break;
1095 } 1143 }
1096 // Cache the new register value so the next run can detect any changes. 1144 default:
1097 last_regs[i] = xreg(i, Reg31IsStackPointer); 1145 UNREACHABLE();
1098 } 1146 }
1099 first_run = false; 1147 }
1100 } 1148
1101 1149
1102 1150 void Simulator::PrintRead(uintptr_t address,
1103 void Simulator::PrintFPRegisters(bool print_all_regs) { 1151 size_t size,
1104 static bool first_run = true; 1152 unsigned reg_code) {
1105 static uint64_t last_regs[kNumberOfFPRegisters]; 1153 USE(size); // Size is unused here.
1106 1154
1107 // Print as many rows of registers as necessary, keeping each individual 1155 // The template is "# x<code>:value <- address".
1108 // register in the same column each time (to make it easy to visually scan 1156 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s",
1109 // for changes). 1157 clr_reg_name, XRegNameForCode(reg_code),
1110 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 1158 clr_reg_value, reg<uint64_t>(reg_code), clr_normal);
1111 if (print_all_regs || first_run || (last_regs[i] != dreg_bits(i))) { 1159
1112 fprintf(stream_, 1160 fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
1113 "# %s %4s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n", 1161 clr_memory_address, address, clr_normal);
1114 clr_fpreg_name, 1162 }
1115 VRegNameForCode(i), 1163
1116 clr_fpreg_value, 1164
1117 dreg_bits(i), 1165 void Simulator::PrintReadFP(uintptr_t address,
1118 clr_normal, 1166 size_t size,
1119 clr_fpreg_name, 1167 unsigned reg_code) {
1120 DRegNameForCode(i), 1168 // The template is "# reg:bits (reg:value) <- address".
1121 clr_fpreg_value, 1169 switch (size) {
1122 dreg(i), 1170 case kSRegSize:
1123 clr_fpreg_name, 1171 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%gf%s)",
1124 SRegNameForCode(i), 1172 clr_fpreg_name, VRegNameForCode(reg_code),
1125 clr_fpreg_value, 1173 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1126 sreg(i), 1174 clr_fpreg_name, SRegNameForCode(reg_code),
1127 clr_normal); 1175 clr_fpreg_value, fpreg<float>(reg_code), clr_normal);
1128 } 1176 break;
1129 // Cache the new register value so the next run can detect any changes. 1177 case kDRegSize:
1130 last_regs[i] = dreg_bits(i); 1178 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)",
1131 } 1179 clr_fpreg_name, VRegNameForCode(reg_code),
1132 first_run = false; 1180 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1133 } 1181 clr_fpreg_name, DRegNameForCode(reg_code),
1134 1182 clr_fpreg_value, fpreg<double>(reg_code), clr_normal);
1135 1183 break;
1136 void Simulator::PrintProcessorState() { 1184 default:
1137 PrintSystemRegisters(); 1185 UNREACHABLE();
1138 PrintRegisters(); 1186 }
1139 PrintFPRegisters(); 1187
1140 } 1188 fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
1141 1189 clr_memory_address, address, clr_normal);
1142 1190 }
1143 void Simulator::PrintWrite(uintptr_t address, uint64_t value, 1191
1144 unsigned num_bytes) { 1192
1145 // The template is "# value -> address". The format string is not used 1193 void Simulator::PrintWrite(uintptr_t address,
1146 // directly in the printf because some compilers struggle with the 1194 size_t size,
1147 // parametrized width field (%0*). 1195 unsigned reg_code) {
1148 const char* format = "# %s0x%0*" PRIx64 "%s -> %s0x%016" PRIxPTR "%s\n"; 1196 // The template is "# reg:value -> address". To keep the trace tidy and
1149 fprintf(stream_, 1197 // readable, the value is aligned with the values in the register trace.
1150 format, 1198 switch (size) {
1151 clr_memory_value, 1199 case kByteSizeInBytes:
1152 num_bytes * 2, // The width in hexadecimal characters. 1200 fprintf(stream_, "# %s%5s<7:0>: %s0x%02" PRIx8 "%s",
1153 value, 1201 clr_reg_name, WRegNameForCode(reg_code),
1154 clr_normal, 1202 clr_reg_value, reg<uint8_t>(reg_code), clr_normal);
1155 clr_memory_address, 1203 break;
1156 address, 1204 case kHalfWordSizeInBytes:
1157 clr_normal); 1205 fprintf(stream_, "# %s%5s<15:0>: %s0x%04" PRIx16 "%s",
1158 } 1206 clr_reg_name, WRegNameForCode(reg_code),
1159 1207 clr_reg_value, reg<uint16_t>(reg_code), clr_normal);
1160 1208 break;
1209 case kWRegSize:
1210 fprintf(stream_, "# %s%5s: %s0x%08" PRIx32 "%s",
1211 clr_reg_name, WRegNameForCode(reg_code),
1212 clr_reg_value, reg<uint32_t>(reg_code), clr_normal);
1213 break;
1214 case kXRegSize:
1215 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s",
1216 clr_reg_name, XRegNameForCode(reg_code),
1217 clr_reg_value, reg<uint64_t>(reg_code), clr_normal);
1218 break;
1219 default:
1220 UNREACHABLE();
1221 }
1222
1223 fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
1224 clr_memory_address, address, clr_normal);
1225 }
1226
1227
1228 void Simulator::PrintWriteFP(uintptr_t address,
1229 size_t size,
1230 unsigned reg_code) {
1231 // The template is "# reg:bits (reg:value) -> address". To keep the trace tidy
1232 // and readable, the value is aligned with the values in the register trace.
1233 switch (size) {
1234 case kSRegSize:
1235 fprintf(stream_, "# %s%5s<31:0>: %s0x%08" PRIx32 "%s (%s%s: %s%gf%s)",
1236 clr_fpreg_name, VRegNameForCode(reg_code),
1237 clr_fpreg_value, fpreg<uint32_t>(reg_code), clr_normal,
1238 clr_fpreg_name, SRegNameForCode(reg_code),
1239 clr_fpreg_value, fpreg<float>(reg_code), clr_normal);
1240 break;
1241 case kDRegSize:
1242 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)",
1243 clr_fpreg_name, VRegNameForCode(reg_code),
1244 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1245 clr_fpreg_name, DRegNameForCode(reg_code),
1246 clr_fpreg_value, fpreg<double>(reg_code), clr_normal);
1247 break;
1248 default:
1249 UNREACHABLE();
1250 }
1251
1252 fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
1253 clr_memory_address, address, clr_normal);
1254 }
1255
1256
1161 // Visitors--------------------------------------------------------------------- 1257 // Visitors---------------------------------------------------------------------
1162 1258
1163 void Simulator::VisitUnimplemented(Instruction* instr) { 1259 void Simulator::VisitUnimplemented(Instruction* instr) {
1164 fprintf(stream_, "Unimplemented instruction at %p: 0x%08" PRIx32 "\n", 1260 fprintf(stream_, "Unimplemented instruction at %p: 0x%08" PRIx32 "\n",
1165 reinterpret_cast<void*>(instr), instr->InstructionBits()); 1261 reinterpret_cast<void*>(instr), instr->InstructionBits());
1166 UNIMPLEMENTED(); 1262 UNIMPLEMENTED();
1167 } 1263 }
1168 1264
1169 1265
1170 void Simulator::VisitUnallocated(Instruction* instr) { 1266 void Simulator::VisitUnallocated(Instruction* instr) {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 case EOR: result = op1 ^ op2; break; 1472 case EOR: result = op1 ^ op2; break;
1377 default: 1473 default:
1378 UNIMPLEMENTED(); 1474 UNIMPLEMENTED();
1379 } 1475 }
1380 1476
1381 if (update_flags) { 1477 if (update_flags) {
1382 nzcv().SetN(CalcNFlag(result)); 1478 nzcv().SetN(CalcNFlag(result));
1383 nzcv().SetZ(CalcZFlag(result)); 1479 nzcv().SetZ(CalcZFlag(result));
1384 nzcv().SetC(0); 1480 nzcv().SetC(0);
1385 nzcv().SetV(0); 1481 nzcv().SetV(0);
1482 LogSystemRegister(NZCV);
1386 } 1483 }
1387 1484
1388 set_reg<T>(instr->Rd(), result, instr->RdMode()); 1485 set_reg<T>(instr->Rd(), result, instr->RdMode());
1389 } 1486 }
1390 1487
1391 1488
1392 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { 1489 void Simulator::VisitConditionalCompareRegister(Instruction* instr) {
1393 if (instr->SixtyFourBits()) { 1490 if (instr->SixtyFourBits()) {
1394 ConditionalCompareHelper(instr, xreg(instr->Rm())); 1491 ConditionalCompareHelper(instr, xreg(instr->Rm()));
1395 } else { 1492 } else {
(...skipping 20 matching lines...) Expand all
1416 // the operands. 1513 // the operands.
1417 if (instr->Mask(ConditionalCompareMask) == CCMP) { 1514 if (instr->Mask(ConditionalCompareMask) == CCMP) {
1418 AddWithCarry<T>(true, op1, ~op2, 1); 1515 AddWithCarry<T>(true, op1, ~op2, 1);
1419 } else { 1516 } else {
1420 DCHECK(instr->Mask(ConditionalCompareMask) == CCMN); 1517 DCHECK(instr->Mask(ConditionalCompareMask) == CCMN);
1421 AddWithCarry<T>(true, op1, op2, 0); 1518 AddWithCarry<T>(true, op1, op2, 0);
1422 } 1519 }
1423 } else { 1520 } else {
1424 // If the condition fails, set the status flags to the nzcv immediate. 1521 // If the condition fails, set the status flags to the nzcv immediate.
1425 nzcv().SetFlags(instr->Nzcv()); 1522 nzcv().SetFlags(instr->Nzcv());
1523 LogSystemRegister(NZCV);
1426 } 1524 }
1427 } 1525 }
1428 1526
1429 1527
1430 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) { 1528 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
1431 int offset = instr->ImmLSUnsigned() << instr->SizeLS(); 1529 int offset = instr->ImmLSUnsigned() << instr->SizeLS();
1432 LoadStoreHelper(instr, offset, Offset); 1530 LoadStoreHelper(instr, offset, Offset);
1433 } 1531 }
1434 1532
1435 1533
(...skipping 20 matching lines...) Expand all
1456 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount); 1554 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount);
1457 LoadStoreHelper(instr, offset, Offset); 1555 LoadStoreHelper(instr, offset, Offset);
1458 } 1556 }
1459 1557
1460 1558
1461 void Simulator::LoadStoreHelper(Instruction* instr, 1559 void Simulator::LoadStoreHelper(Instruction* instr,
1462 int64_t offset, 1560 int64_t offset,
1463 AddrMode addrmode) { 1561 AddrMode addrmode) {
1464 unsigned srcdst = instr->Rt(); 1562 unsigned srcdst = instr->Rt();
1465 unsigned addr_reg = instr->Rn(); 1563 unsigned addr_reg = instr->Rn();
1466 uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode); 1564 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1467 uint8_t* stack = NULL; 1565 uintptr_t stack = 0;
1468 1566
1469 // Handle the writeback for stores before the store. On a CPU the writeback 1567 // Handle the writeback for stores before the store. On a CPU the writeback
1470 // and the store are atomic, but when running on the simulator it is possible 1568 // and the store are atomic, but when running on the simulator it is possible
1471 // to be interrupted in between. The simulator is not thread safe and V8 does 1569 // to be interrupted in between. The simulator is not thread safe and V8 does
1472 // not require it to be to run JavaScript therefore the profiler may sample 1570 // not require it to be to run JavaScript therefore the profiler may sample
1473 // the "simulated" CPU in the middle of load/store with writeback. The code 1571 // the "simulated" CPU in the middle of load/store with writeback. The code
1474 // below ensures that push operations are safe even when interrupted: the 1572 // below ensures that push operations are safe even when interrupted: the
1475 // stack pointer will be decremented before adding an element to the stack. 1573 // stack pointer will be decremented before adding an element to the stack.
1476 if (instr->IsStore()) { 1574 if (instr->IsStore()) {
1477 LoadStoreWriteBack(addr_reg, offset, addrmode); 1575 LoadStoreWriteBack(addr_reg, offset, addrmode);
1478 1576
1479 // For store the address post writeback is used to check access below the 1577 // For store the address post writeback is used to check access below the
1480 // stack. 1578 // stack.
1481 stack = reinterpret_cast<uint8_t*>(sp()); 1579 stack = sp();
1482 } 1580 }
1483 1581
1484 LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask)); 1582 LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask));
1485 switch (op) { 1583 switch (op) {
1486 case LDRB_w: set_wreg(srcdst, MemoryRead<uint8_t>(address)); break; 1584 // Use _no_log variants to suppress the register trace (LOG_REGS,
1487 case LDRH_w: set_wreg(srcdst, MemoryRead<uint16_t>(address)); break; 1585 // LOG_FP_REGS). We will print a more detailed log.
1488 case LDR_w: set_wreg(srcdst, MemoryRead<uint32_t>(address)); break; 1586 case LDRB_w: set_wreg_no_log(srcdst, MemoryRead<uint8_t>(address)); break;
1489 case LDR_x: set_xreg(srcdst, MemoryRead<uint64_t>(address)); break; 1587 case LDRH_w: set_wreg_no_log(srcdst, MemoryRead<uint16_t>(address)); break;
1490 case LDRSB_w: set_wreg(srcdst, MemoryRead<int8_t>(address)); break; 1588 case LDR_w: set_wreg_no_log(srcdst, MemoryRead<uint32_t>(address)); break;
1491 case LDRSH_w: set_wreg(srcdst, MemoryRead<int16_t>(address)); break; 1589 case LDR_x: set_xreg_no_log(srcdst, MemoryRead<uint64_t>(address)); break;
1492 case LDRSB_x: set_xreg(srcdst, MemoryRead<int8_t>(address)); break; 1590 case LDRSB_w: set_wreg_no_log(srcdst, MemoryRead<int8_t>(address)); break;
1493 case LDRSH_x: set_xreg(srcdst, MemoryRead<int16_t>(address)); break; 1591 case LDRSH_w: set_wreg_no_log(srcdst, MemoryRead<int16_t>(address)); break;
1494 case LDRSW_x: set_xreg(srcdst, MemoryRead<int32_t>(address)); break; 1592 case LDRSB_x: set_xreg_no_log(srcdst, MemoryRead<int8_t>(address)); break;
1495 case LDR_s: set_sreg(srcdst, MemoryRead<float>(address)); break; 1593 case LDRSH_x: set_xreg_no_log(srcdst, MemoryRead<int16_t>(address)); break;
1496 case LDR_d: set_dreg(srcdst, MemoryRead<double>(address)); break; 1594 case LDRSW_x: set_xreg_no_log(srcdst, MemoryRead<int32_t>(address)); break;
1595 case LDR_s: set_sreg_no_log(srcdst, MemoryRead<float>(address)); break;
1596 case LDR_d: set_dreg_no_log(srcdst, MemoryRead<double>(address)); break;
1497 1597
1498 case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break; 1598 case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break;
1499 case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break; 1599 case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break;
1500 case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break; 1600 case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break;
1501 case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break; 1601 case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break;
1502 case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break; 1602 case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break;
1503 case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break; 1603 case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break;
1504 1604
1505 default: UNIMPLEMENTED(); 1605 default: UNIMPLEMENTED();
1506 } 1606 }
1507 1607
1608 // Print a detailed trace (including the memory address) instead of the basic
1609 // register:value trace generated by set_*reg().
1610 size_t access_size = 1 << instr->SizeLS();
1611 if (instr->IsLoad()) {
1612 if ((op == LDR_s) || (op == LDR_d)) {
1613 LogReadFP(address, access_size, srcdst);
1614 } else {
1615 LogRead(address, access_size, srcdst);
1616 }
1617 } else {
1618 if ((op == STR_s) || (op == STR_d)) {
1619 LogWriteFP(address, access_size, srcdst);
1620 } else {
1621 LogWrite(address, access_size, srcdst);
1622 }
1623 }
1624
1508 // Handle the writeback for loads after the load to ensure safe pop 1625 // Handle the writeback for loads after the load to ensure safe pop
1509 // operation even when interrupted in the middle of it. The stack pointer 1626 // operation even when interrupted in the middle of it. The stack pointer
1510 // is only updated after the load so pop(fp) will never break the invariant 1627 // is only updated after the load so pop(fp) will never break the invariant
1511 // sp <= fp expected while walking the stack in the sampler. 1628 // sp <= fp expected while walking the stack in the sampler.
1512 if (instr->IsLoad()) { 1629 if (instr->IsLoad()) {
1513 // For loads the address pre writeback is used to check access below the 1630 // For loads the address pre writeback is used to check access below the
1514 // stack. 1631 // stack.
1515 stack = reinterpret_cast<uint8_t*>(sp()); 1632 stack = sp();
1516 1633
1517 LoadStoreWriteBack(addr_reg, offset, addrmode); 1634 LoadStoreWriteBack(addr_reg, offset, addrmode);
1518 } 1635 }
1519 1636
1520 // Accesses below the stack pointer (but above the platform stack limit) are 1637 // Accesses below the stack pointer (but above the platform stack limit) are
1521 // not allowed in the ABI. 1638 // not allowed in the ABI.
1522 CheckMemoryAccess(address, stack); 1639 CheckMemoryAccess(address, stack);
1523 } 1640 }
1524 1641
1525 1642
(...skipping 15 matching lines...) Expand all
1541 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) { 1658 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) {
1542 LoadStorePairHelper(instr, Offset); 1659 LoadStorePairHelper(instr, Offset);
1543 } 1660 }
1544 1661
1545 1662
1546 void Simulator::LoadStorePairHelper(Instruction* instr, 1663 void Simulator::LoadStorePairHelper(Instruction* instr,
1547 AddrMode addrmode) { 1664 AddrMode addrmode) {
1548 unsigned rt = instr->Rt(); 1665 unsigned rt = instr->Rt();
1549 unsigned rt2 = instr->Rt2(); 1666 unsigned rt2 = instr->Rt2();
1550 unsigned addr_reg = instr->Rn(); 1667 unsigned addr_reg = instr->Rn();
1551 int offset = instr->ImmLSPair() << instr->SizeLSPair(); 1668 size_t access_size = 1 << instr->SizeLSPair();
1552 uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode); 1669 int64_t offset = instr->ImmLSPair() * access_size;
1553 uint8_t* stack = NULL; 1670 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1671 uintptr_t address2 = address + access_size;
1672 uintptr_t stack = 0;
1554 1673
1555 // Handle the writeback for stores before the store. On a CPU the writeback 1674 // Handle the writeback for stores before the store. On a CPU the writeback
1556 // and the store are atomic, but when running on the simulator it is possible 1675 // and the store are atomic, but when running on the simulator it is possible
1557 // to be interrupted in between. The simulator is not thread safe and V8 does 1676 // to be interrupted in between. The simulator is not thread safe and V8 does
1558 // not require it to be to run JavaScript therefore the profiler may sample 1677 // not require it to be to run JavaScript therefore the profiler may sample
1559 // the "simulated" CPU in the middle of load/store with writeback. The code 1678 // the "simulated" CPU in the middle of load/store with writeback. The code
1560 // below ensures that push operations are safe even when interrupted: the 1679 // below ensures that push operations are safe even when interrupted: the
1561 // stack pointer will be decremented before adding an element to the stack. 1680 // stack pointer will be decremented before adding an element to the stack.
1562 if (instr->IsStore()) { 1681 if (instr->IsStore()) {
1563 LoadStoreWriteBack(addr_reg, offset, addrmode); 1682 LoadStoreWriteBack(addr_reg, offset, addrmode);
1564 1683
1565 // For store the address post writeback is used to check access below the 1684 // For store the address post writeback is used to check access below the
1566 // stack. 1685 // stack.
1567 stack = reinterpret_cast<uint8_t*>(sp()); 1686 stack = sp();
1568 } 1687 }
1569 1688
1570 LoadStorePairOp op = 1689 LoadStorePairOp op =
1571 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); 1690 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask));
1572 1691
1573 // 'rt' and 'rt2' can only be aliased for stores. 1692 // 'rt' and 'rt2' can only be aliased for stores.
1574 DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2)); 1693 DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2));
1575 1694
1576 switch (op) { 1695 switch (op) {
1696 // Use _no_log variants to suppress the register trace (LOG_REGS,
1697 // LOG_FP_REGS). We will print a more detailed log.
1577 case LDP_w: { 1698 case LDP_w: {
1578 set_wreg(rt, MemoryRead<uint32_t>(address)); 1699 DCHECK(access_size == kWRegSize);
1579 set_wreg(rt2, MemoryRead<uint32_t>(address + kWRegSize)); 1700 set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1701 set_wreg_no_log(rt2, MemoryRead<uint32_t>(address2));
1580 break; 1702 break;
1581 } 1703 }
1582 case LDP_s: { 1704 case LDP_s: {
1583 set_sreg(rt, MemoryRead<float>(address)); 1705 DCHECK(access_size == kSRegSize);
1584 set_sreg(rt2, MemoryRead<float>(address + kSRegSize)); 1706 set_sreg_no_log(rt, MemoryRead<float>(address));
1707 set_sreg_no_log(rt2, MemoryRead<float>(address2));
1585 break; 1708 break;
1586 } 1709 }
1587 case LDP_x: { 1710 case LDP_x: {
1588 set_xreg(rt, MemoryRead<uint64_t>(address)); 1711 DCHECK(access_size == kXRegSize);
1589 set_xreg(rt2, MemoryRead<uint64_t>(address + kXRegSize)); 1712 set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1713 set_xreg_no_log(rt2, MemoryRead<uint64_t>(address2));
1590 break; 1714 break;
1591 } 1715 }
1592 case LDP_d: { 1716 case LDP_d: {
1593 set_dreg(rt, MemoryRead<double>(address)); 1717 DCHECK(access_size == kDRegSize);
1594 set_dreg(rt2, MemoryRead<double>(address + kDRegSize)); 1718 set_dreg_no_log(rt, MemoryRead<double>(address));
1719 set_dreg_no_log(rt2, MemoryRead<double>(address2));
1595 break; 1720 break;
1596 } 1721 }
1597 case LDPSW_x: { 1722 case LDPSW_x: {
1598 set_xreg(rt, MemoryRead<int32_t>(address)); 1723 DCHECK(access_size == kWRegSize);
1599 set_xreg(rt2, MemoryRead<int32_t>(address + kWRegSize)); 1724 set_xreg_no_log(rt, MemoryRead<int32_t>(address));
1725 set_xreg_no_log(rt2, MemoryRead<int32_t>(address2));
1600 break; 1726 break;
1601 } 1727 }
1602 case STP_w: { 1728 case STP_w: {
1729 DCHECK(access_size == kWRegSize);
1603 MemoryWrite<uint32_t>(address, wreg(rt)); 1730 MemoryWrite<uint32_t>(address, wreg(rt));
1604 MemoryWrite<uint32_t>(address + kWRegSize, wreg(rt2)); 1731 MemoryWrite<uint32_t>(address2, wreg(rt2));
1605 break; 1732 break;
1606 } 1733 }
1607 case STP_s: { 1734 case STP_s: {
1735 DCHECK(access_size == kSRegSize);
1608 MemoryWrite<float>(address, sreg(rt)); 1736 MemoryWrite<float>(address, sreg(rt));
1609 MemoryWrite<float>(address + kSRegSize, sreg(rt2)); 1737 MemoryWrite<float>(address2, sreg(rt2));
1610 break; 1738 break;
1611 } 1739 }
1612 case STP_x: { 1740 case STP_x: {
1741 DCHECK(access_size == kXRegSize);
1613 MemoryWrite<uint64_t>(address, xreg(rt)); 1742 MemoryWrite<uint64_t>(address, xreg(rt));
1614 MemoryWrite<uint64_t>(address + kXRegSize, xreg(rt2)); 1743 MemoryWrite<uint64_t>(address2, xreg(rt2));
1615 break; 1744 break;
1616 } 1745 }
1617 case STP_d: { 1746 case STP_d: {
1747 DCHECK(access_size == kDRegSize);
1618 MemoryWrite<double>(address, dreg(rt)); 1748 MemoryWrite<double>(address, dreg(rt));
1619 MemoryWrite<double>(address + kDRegSize, dreg(rt2)); 1749 MemoryWrite<double>(address2, dreg(rt2));
1620 break; 1750 break;
1621 } 1751 }
1622 default: UNREACHABLE(); 1752 default: UNREACHABLE();
1623 } 1753 }
1624 1754
1755 // Print a detailed trace (including the memory address) instead of the basic
1756 // register:value trace generated by set_*reg().
1757 if (instr->IsLoad()) {
1758 if ((op == LDP_s) || (op == LDP_d)) {
1759 LogReadFP(address, access_size, rt);
1760 LogReadFP(address2, access_size, rt2);
1761 } else {
1762 LogRead(address, access_size, rt);
1763 LogRead(address2, access_size, rt2);
1764 }
1765 } else {
1766 if ((op == STP_s) || (op == STP_d)) {
1767 LogWriteFP(address, access_size, rt);
1768 LogWriteFP(address2, access_size, rt2);
1769 } else {
1770 LogWrite(address, access_size, rt);
1771 LogWrite(address2, access_size, rt2);
1772 }
1773 }
1774
1625 // Handle the writeback for loads after the load to ensure safe pop 1775 // Handle the writeback for loads after the load to ensure safe pop
1626 // operation even when interrupted in the middle of it. The stack pointer 1776 // operation even when interrupted in the middle of it. The stack pointer
1627 // is only updated after the load so pop(fp) will never break the invariant 1777 // is only updated after the load so pop(fp) will never break the invariant
1628 // sp <= fp expected while walking the stack in the sampler. 1778 // sp <= fp expected while walking the stack in the sampler.
1629 if (instr->IsLoad()) { 1779 if (instr->IsLoad()) {
1630 // For loads the address pre writeback is used to check access below the 1780 // For loads the address pre writeback is used to check access below the
1631 // stack. 1781 // stack.
1632 stack = reinterpret_cast<uint8_t*>(sp()); 1782 stack = sp();
1633 1783
1634 LoadStoreWriteBack(addr_reg, offset, addrmode); 1784 LoadStoreWriteBack(addr_reg, offset, addrmode);
1635 } 1785 }
1636 1786
1637 // Accesses below the stack pointer (but above the platform stack limit) are 1787 // Accesses below the stack pointer (but above the platform stack limit) are
1638 // not allowed in the ABI. 1788 // not allowed in the ABI.
1639 CheckMemoryAccess(address, stack); 1789 CheckMemoryAccess(address, stack);
1640 } 1790 }
1641 1791
1642 1792
1643 void Simulator::VisitLoadLiteral(Instruction* instr) { 1793 void Simulator::VisitLoadLiteral(Instruction* instr) {
1644 uint8_t* address = instr->LiteralAddress(); 1794 uintptr_t address = instr->LiteralAddress();
1645 unsigned rt = instr->Rt(); 1795 unsigned rt = instr->Rt();
1646 1796
1647 switch (instr->Mask(LoadLiteralMask)) { 1797 switch (instr->Mask(LoadLiteralMask)) {
1648 case LDR_w_lit: set_wreg(rt, MemoryRead<uint32_t>(address)); break; 1798 // Use _no_log variants to suppress the register trace (LOG_REGS,
1649 case LDR_x_lit: set_xreg(rt, MemoryRead<uint64_t>(address)); break; 1799 // LOG_FP_REGS), then print a more detailed log.
1650 case LDR_s_lit: set_sreg(rt, MemoryRead<float>(address)); break; 1800 case LDR_w_lit:
1651 case LDR_d_lit: set_dreg(rt, MemoryRead<double>(address)); break; 1801 set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1802 LogRead(address, kWRegSize, rt);
1803 break;
1804 case LDR_x_lit:
1805 set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1806 LogRead(address, kXRegSize, rt);
1807 break;
1808 case LDR_s_lit:
1809 set_sreg_no_log(rt, MemoryRead<float>(address));
1810 LogReadFP(address, kSRegSize, rt);
1811 break;
1812 case LDR_d_lit:
1813 set_dreg_no_log(rt, MemoryRead<double>(address));
1814 LogReadFP(address, kDRegSize, rt);
1815 break;
1652 default: UNREACHABLE(); 1816 default: UNREACHABLE();
1653 } 1817 }
1654 } 1818 }
1655 1819
1656 1820
1657 uint8_t* Simulator::LoadStoreAddress(unsigned addr_reg, 1821 uintptr_t Simulator::LoadStoreAddress(unsigned addr_reg, int64_t offset,
1658 int64_t offset, 1822 AddrMode addrmode) {
1659 AddrMode addrmode) {
1660 const unsigned kSPRegCode = kSPRegInternalCode & kRegCodeMask; 1823 const unsigned kSPRegCode = kSPRegInternalCode & kRegCodeMask;
1661 int64_t address = xreg(addr_reg, Reg31IsStackPointer); 1824 uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1662 if ((addr_reg == kSPRegCode) && ((address % 16) != 0)) { 1825 if ((addr_reg == kSPRegCode) && ((address % 16) != 0)) {
1663 // When the base register is SP the stack pointer is required to be 1826 // When the base register is SP the stack pointer is required to be
1664 // quadword aligned prior to the address calculation and write-backs. 1827 // quadword aligned prior to the address calculation and write-backs.
1665 // Misalignment will cause a stack alignment fault. 1828 // Misalignment will cause a stack alignment fault.
1666 FATAL("ALIGNMENT EXCEPTION"); 1829 FATAL("ALIGNMENT EXCEPTION");
1667 } 1830 }
1668 1831
1669 if ((addrmode == Offset) || (addrmode == PreIndex)) { 1832 if ((addrmode == Offset) || (addrmode == PreIndex)) {
1670 address += offset; 1833 address += offset;
1671 } 1834 }
1672 1835
1673 return reinterpret_cast<uint8_t*>(address); 1836 return address;
1674 } 1837 }
1675 1838
1676 1839
1677 void Simulator::LoadStoreWriteBack(unsigned addr_reg, 1840 void Simulator::LoadStoreWriteBack(unsigned addr_reg,
1678 int64_t offset, 1841 int64_t offset,
1679 AddrMode addrmode) { 1842 AddrMode addrmode) {
1680 if ((addrmode == PreIndex) || (addrmode == PostIndex)) { 1843 if ((addrmode == PreIndex) || (addrmode == PostIndex)) {
1681 DCHECK(offset != 0); 1844 DCHECK(offset != 0);
1682 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 1845 uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1683 set_reg(addr_reg, address + offset, Reg31IsStackPointer); 1846 set_reg(addr_reg, address + offset, Reg31IsStackPointer);
1684 } 1847 }
1685 } 1848 }
1686 1849
1687 1850
1688 void Simulator::CheckMemoryAccess(uint8_t* address, uint8_t* stack) { 1851 void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) {
1689 if ((address >= stack_limit_) && (address < stack)) { 1852 if ((address >= stack_limit_) && (address < stack)) {
1690 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n"); 1853 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n");
1691 fprintf(stream_, " sp is here: 0x%16p\n", stack); 1854 fprintf(stream_, " sp is here: 0x%016" PRIx64 "\n", stack);
1692 fprintf(stream_, " access was here: 0x%16p\n", address); 1855 fprintf(stream_, " access was here: 0x%016" PRIx64 "\n", address);
1693 fprintf(stream_, " stack limit is here: 0x%16p\n", stack_limit_); 1856 fprintf(stream_, " stack limit is here: 0x%016" PRIx64 "\n", stack_limit_);
1694 fprintf(stream_, "\n"); 1857 fprintf(stream_, "\n");
1695 FATAL("ACCESS BELOW STACK POINTER"); 1858 FATAL("ACCESS BELOW STACK POINTER");
1696 } 1859 }
1697 } 1860 }
1698 1861
1699 1862
1700 void Simulator::VisitMoveWideImmediate(Instruction* instr) { 1863 void Simulator::VisitMoveWideImmediate(Instruction* instr) {
1701 MoveWideImmediateOp mov_op = 1864 MoveWideImmediateOp mov_op =
1702 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); 1865 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
1703 int64_t new_xn_val = 0; 1866 int64_t new_xn_val = 0;
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2238 case FCCMP_d: { 2401 case FCCMP_d: {
2239 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 2402 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
2240 // If the condition passes, set the status flags to the result of 2403 // If the condition passes, set the status flags to the result of
2241 // comparing the operands. 2404 // comparing the operands.
2242 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits 2405 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits
2243 : kSRegSizeInBits; 2406 : kSRegSizeInBits;
2244 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm())); 2407 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm()));
2245 } else { 2408 } else {
2246 // If the condition fails, set the status flags to the nzcv immediate. 2409 // If the condition fails, set the status flags to the nzcv immediate.
2247 nzcv().SetFlags(instr->Nzcv()); 2410 nzcv().SetFlags(instr->Nzcv());
2411 LogSystemRegister(NZCV);
2248 } 2412 }
2249 break; 2413 break;
2250 } 2414 }
2251 default: UNIMPLEMENTED(); 2415 default: UNIMPLEMENTED();
2252 } 2416 }
2253 } 2417 }
2254 2418
2255 2419
2256 void Simulator::VisitFPConditionalSelect(Instruction* instr) { 2420 void Simulator::VisitFPConditionalSelect(Instruction* instr) {
2257 AssertSupportedFPCR(); 2421 AssertSupportedFPCR();
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 case MRS: { 3184 case MRS: {
3021 switch (instr->ImmSystemRegister()) { 3185 switch (instr->ImmSystemRegister()) {
3022 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break; 3186 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break;
3023 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break; 3187 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break;
3024 default: UNIMPLEMENTED(); 3188 default: UNIMPLEMENTED();
3025 } 3189 }
3026 break; 3190 break;
3027 } 3191 }
3028 case MSR: { 3192 case MSR: {
3029 switch (instr->ImmSystemRegister()) { 3193 switch (instr->ImmSystemRegister()) {
3030 case NZCV: nzcv().SetRawValue(xreg(instr->Rt())); break; 3194 case NZCV:
3031 case FPCR: fpcr().SetRawValue(xreg(instr->Rt())); break; 3195 nzcv().SetRawValue(xreg(instr->Rt()));
3196 LogSystemRegister(NZCV);
3197 break;
3198 case FPCR:
3199 fpcr().SetRawValue(xreg(instr->Rt()));
3200 LogSystemRegister(FPCR);
3201 break;
3032 default: UNIMPLEMENTED(); 3202 default: UNIMPLEMENTED();
3033 } 3203 }
3034 break; 3204 break;
3035 } 3205 }
3036 } 3206 }
3037 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 3207 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
3038 DCHECK(instr->Mask(SystemHintMask) == HINT); 3208 DCHECK(instr->Mask(SystemHintMask) == HINT);
3039 switch (instr->ImmHint()) { 3209 switch (instr->ImmHint()) {
3040 case NOP: break; 3210 case NOP: break;
3041 default: UNIMPLEMENTED(); 3211 default: UNIMPLEMENTED();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3232 3402
3233 // Disassemble. 3403 // Disassemble.
3234 PrintInstructionsAt(reinterpret_cast<Instruction*>(address), 3404 PrintInstructionsAt(reinterpret_cast<Instruction*>(address),
3235 n_of_instrs_to_disasm); 3405 n_of_instrs_to_disasm);
3236 PrintF("\n"); 3406 PrintF("\n");
3237 3407
3238 // print / p ------------------------------------------------------------- 3408 // print / p -------------------------------------------------------------
3239 } else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) { 3409 } else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) {
3240 if (argc == 2) { 3410 if (argc == 2) {
3241 if (strcmp(arg1, "all") == 0) { 3411 if (strcmp(arg1, "all") == 0) {
3242 PrintRegisters(true); 3412 PrintRegisters();
3243 PrintFPRegisters(true); 3413 PrintFPRegisters();
3244 } else { 3414 } else {
3245 if (!PrintValue(arg1)) { 3415 if (!PrintValue(arg1)) {
3246 PrintF("%s unrecognized\n", arg1); 3416 PrintF("%s unrecognized\n", arg1);
3247 } 3417 }
3248 } 3418 }
3249 } else { 3419 } else {
3250 PrintF( 3420 PrintF(
3251 "print <register>\n" 3421 "print <register>\n"
3252 " Print the content of a register. (alias 'p')\n" 3422 " Print the content of a register. (alias 'p')\n"
3253 " 'print all' will print all registers.\n" 3423 " 'print all' will print all registers.\n"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
3437 char const *message = 3607 char const *message =
3438 reinterpret_cast<char const*>( 3608 reinterpret_cast<char const*>(
3439 pc_->InstructionAtOffset(kDebugMessageOffset)); 3609 pc_->InstructionAtOffset(kDebugMessageOffset));
3440 3610
3441 // Always print something when we hit a debug point that breaks. 3611 // Always print something when we hit a debug point that breaks.
3442 // We are going to break, so printing something is not an issue in 3612 // We are going to break, so printing something is not an issue in
3443 // terms of speed. 3613 // terms of speed.
3444 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) { 3614 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) {
3445 if (message != NULL) { 3615 if (message != NULL) {
3446 PrintF(stream_, 3616 PrintF(stream_,
3447 "%sDebugger hit %d: %s%s%s\n", 3617 "# %sDebugger hit %d: %s%s%s\n",
3448 clr_debug_number, 3618 clr_debug_number,
3449 code, 3619 code,
3450 clr_debug_message, 3620 clr_debug_message,
3451 message, 3621 message,
3452 clr_normal); 3622 clr_normal);
3453 } else { 3623 } else {
3454 PrintF(stream_, 3624 PrintF(stream_,
3455 "%sDebugger hit %d.%s\n", 3625 "# %sDebugger hit %d.%s\n",
3456 clr_debug_number, 3626 clr_debug_number,
3457 code, 3627 code,
3458 clr_normal); 3628 clr_normal);
3459 } 3629 }
3460 } 3630 }
3461 3631
3462 // Other options. 3632 // Other options.
3463 switch (parameters & kDebuggerTracingDirectivesMask) { 3633 switch (parameters & kDebuggerTracingDirectivesMask) {
3464 case TRACE_ENABLE: 3634 case TRACE_ENABLE:
3465 set_log_parameters(log_parameters() | parameters); 3635 set_log_parameters(log_parameters() | parameters);
3466 if (parameters & LOG_SYS_REGS) { PrintSystemRegisters(); } 3636 if (parameters & LOG_SYS_REGS) { PrintSystemRegisters(); }
3467 if (parameters & LOG_REGS) { PrintRegisters(); } 3637 if (parameters & LOG_REGS) { PrintRegisters(); }
3468 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); } 3638 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); }
3469 break; 3639 break;
3470 case TRACE_DISABLE: 3640 case TRACE_DISABLE:
3471 set_log_parameters(log_parameters() & ~parameters); 3641 set_log_parameters(log_parameters() & ~parameters);
3472 break; 3642 break;
3473 case TRACE_OVERRIDE: 3643 case TRACE_OVERRIDE:
3474 set_log_parameters(parameters); 3644 set_log_parameters(parameters);
3475 break; 3645 break;
3476 default: 3646 default:
3477 // We don't support a one-shot LOG_DISASM. 3647 // We don't support a one-shot LOG_DISASM.
3478 DCHECK((parameters & LOG_DISASM) == 0); 3648 DCHECK((parameters & LOG_DISASM) == 0);
3479 // Don't print information that is already being traced. 3649 // Don't print information that is already being traced.
3480 parameters &= ~log_parameters(); 3650 parameters &= ~log_parameters();
3481 // Print the requested information. 3651 // Print the requested information.
3482 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true); 3652 if (parameters & LOG_SYS_REGS) PrintSystemRegisters();
3483 if (parameters & LOG_REGS) PrintRegisters(true); 3653 if (parameters & LOG_REGS) PrintRegisters();
3484 if (parameters & LOG_FP_REGS) PrintFPRegisters(true); 3654 if (parameters & LOG_FP_REGS) PrintFPRegisters();
3485 } 3655 }
3486 3656
3487 // The stop parameters are inlined in the code. Skip them: 3657 // The stop parameters are inlined in the code. Skip them:
3488 // - Skip to the end of the message string. 3658 // - Skip to the end of the message string.
3489 size_t size = kDebugMessageOffset + strlen(message) + 1; 3659 size_t size = kDebugMessageOffset + strlen(message) + 1;
3490 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize)); 3660 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize));
3491 // - Verify that the unreachable marker is present. 3661 // - Verify that the unreachable marker is present.
3492 DCHECK(pc_->Mask(ExceptionMask) == HLT); 3662 DCHECK(pc_->Mask(ExceptionMask) == HLT);
3493 DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable); 3663 DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable);
3494 // - Skip past the unreachable marker. 3664 // - Skip past the unreachable marker.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 3813
3644 delete[] format; 3814 delete[] format;
3645 } 3815 }
3646 3816
3647 3817
3648 #endif // USE_SIMULATOR 3818 #endif // USE_SIMULATOR
3649 3819
3650 } } // namespace v8::internal 3820 } } // namespace v8::internal
3651 3821
3652 #endif // V8_TARGET_ARCH_ARM64 3822 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698