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

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

Issue 551823004: Reland r23732: ARM64: Fix and improve --trace-sim register trace. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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);
768 // The modulo operator has no effect here, but it silences a broken GCC
769 // warning about out-of-bounds array accesses.
770 code %= kNumberOfRegisters;
771
769 // If the code represents the stack pointer, index the name after zr. 772 // If the code represents the stack pointer, index the name after zr.
770 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 773 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
771 code = kZeroRegCode + 1; 774 code = kZeroRegCode + 1;
772 } 775 }
773 return wreg_names[code]; 776 return wreg_names[code];
774 } 777 }
775 778
776 779
777 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) { 780 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) {
781 STATIC_ASSERT(arraysize(Simulator::xreg_names) == (kNumberOfRegisters + 1));
778 DCHECK(code < kNumberOfRegisters); 782 DCHECK(code < kNumberOfRegisters);
783 code %= kNumberOfRegisters;
784
779 // If the code represents the stack pointer, index the name after zr. 785 // If the code represents the stack pointer, index the name after zr.
780 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 786 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
781 code = kZeroRegCode + 1; 787 code = kZeroRegCode + 1;
782 } 788 }
783 return xreg_names[code]; 789 return xreg_names[code];
784 } 790 }
785 791
786 792
787 const char* Simulator::SRegNameForCode(unsigned code) { 793 const char* Simulator::SRegNameForCode(unsigned code) {
794 STATIC_ASSERT(arraysize(Simulator::sreg_names) == kNumberOfFPRegisters);
788 DCHECK(code < kNumberOfFPRegisters); 795 DCHECK(code < kNumberOfFPRegisters);
789 return sreg_names[code]; 796 return sreg_names[code % kNumberOfFPRegisters];
790 } 797 }
791 798
792 799
793 const char* Simulator::DRegNameForCode(unsigned code) { 800 const char* Simulator::DRegNameForCode(unsigned code) {
801 STATIC_ASSERT(arraysize(Simulator::dreg_names) == kNumberOfFPRegisters);
794 DCHECK(code < kNumberOfFPRegisters); 802 DCHECK(code < kNumberOfFPRegisters);
795 return dreg_names[code]; 803 return dreg_names[code % kNumberOfFPRegisters];
796 } 804 }
797 805
798 806
799 const char* Simulator::VRegNameForCode(unsigned code) { 807 const char* Simulator::VRegNameForCode(unsigned code) {
808 STATIC_ASSERT(arraysize(Simulator::vreg_names) == kNumberOfFPRegisters);
800 DCHECK(code < kNumberOfFPRegisters); 809 DCHECK(code < kNumberOfFPRegisters);
801 return vreg_names[code]; 810 return vreg_names[code % kNumberOfFPRegisters];
802 } 811 }
803 812
804 813
805 int Simulator::CodeFromName(const char* name) { 814 int Simulator::CodeFromName(const char* name) {
806 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 815 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
807 if ((strcmp(xreg_names[i], name) == 0) || 816 if ((strcmp(xreg_names[i], name) == 0) ||
808 (strcmp(wreg_names[i], name) == 0)) { 817 (strcmp(wreg_names[i], name) == 0)) {
809 return i; 818 return i;
810 } 819 }
811 } 820 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0); 857 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0);
849 858
850 N = CalcNFlag(result); 859 N = CalcNFlag(result);
851 Z = CalcZFlag(result); 860 Z = CalcZFlag(result);
852 861
853 if (set_flags) { 862 if (set_flags) {
854 nzcv().SetN(N); 863 nzcv().SetN(N);
855 nzcv().SetZ(Z); 864 nzcv().SetZ(Z);
856 nzcv().SetC(C); 865 nzcv().SetC(C);
857 nzcv().SetV(V); 866 nzcv().SetV(V);
867 LogSystemRegister(NZCV);
858 } 868 }
859 return result; 869 return result;
860 } 870 }
861 871
862 872
863 template<typename T> 873 template<typename T>
864 void Simulator::AddSubWithCarry(Instruction* instr) { 874 void Simulator::AddSubWithCarry(Instruction* instr) {
865 T op2 = reg<T>(instr->Rm()); 875 T op2 = reg<T>(instr->Rm());
866 T new_val; 876 T new_val;
867 877
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 nzcv().SetRawValue(FPUnorderedFlag); 981 nzcv().SetRawValue(FPUnorderedFlag);
972 } else if (val0 < val1) { 982 } else if (val0 < val1) {
973 nzcv().SetRawValue(FPLessThanFlag); 983 nzcv().SetRawValue(FPLessThanFlag);
974 } else if (val0 > val1) { 984 } else if (val0 > val1) {
975 nzcv().SetRawValue(FPGreaterThanFlag); 985 nzcv().SetRawValue(FPGreaterThanFlag);
976 } else if (val0 == val1) { 986 } else if (val0 == val1) {
977 nzcv().SetRawValue(FPEqualFlag); 987 nzcv().SetRawValue(FPEqualFlag);
978 } else { 988 } else {
979 UNREACHABLE(); 989 UNREACHABLE();
980 } 990 }
991 LogSystemRegister(NZCV);
981 } 992 }
982 993
983 994
984 void Simulator::SetBreakpoint(Instruction* location) { 995 void Simulator::SetBreakpoint(Instruction* location) {
985 for (unsigned i = 0; i < breakpoints_.size(); i++) { 996 for (unsigned i = 0; i < breakpoints_.size(); i++) {
986 if (breakpoints_.at(i).location == location) { 997 if (breakpoints_.at(i).location == location) {
987 PrintF(stream_, 998 PrintF(stream_,
988 "Existing breakpoint at %p was %s\n", 999 "Existing breakpoint at %p was %s\n",
989 reinterpret_cast<void*>(location), 1000 reinterpret_cast<void*>(location),
990 breakpoints_.at(i).enabled ? "disabled" : "enabled"); 1001 breakpoints_.at(i).enabled ? "disabled" : "enabled");
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 1048
1038 1049
1039 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) { 1050 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) {
1040 Instruction* end = start->InstructionAtOffset(count * kInstructionSize); 1051 Instruction* end = start->InstructionAtOffset(count * kInstructionSize);
1041 for (Instruction* pc = start; pc < end; pc = pc->following()) { 1052 for (Instruction* pc = start; pc < end; pc = pc->following()) {
1042 disassembler_decoder_->Decode(pc); 1053 disassembler_decoder_->Decode(pc);
1043 } 1054 }
1044 } 1055 }
1045 1056
1046 1057
1047 void Simulator::PrintSystemRegisters(bool print_all) { 1058 void Simulator::PrintSystemRegisters() {
1048 static bool first_run = true; 1059 PrintSystemRegister(NZCV);
1049 1060 PrintSystemRegister(FPCR);
1050 static SimSystemRegister last_nzcv; 1061 }
1051 if (print_all || first_run || (last_nzcv.RawValue() != nzcv().RawValue())) { 1062
1052 fprintf(stream_, "# %sFLAGS: %sN:%d Z:%d C:%d V:%d%s\n", 1063
1053 clr_flag_name, 1064 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++) { 1065 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
1086 if (print_all_regs || first_run || 1066 PrintRegister(i);
1087 (last_regs[i] != xreg(i, Reg31IsStackPointer))) { 1067 }
1068 }
1069
1070
1071 void Simulator::PrintFPRegisters() {
1072 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
1073 PrintFPRegister(i);
1074 }
1075 }
1076
1077
1078 void Simulator::PrintRegister(unsigned code, Reg31Mode r31mode) {
1079 // Don't print writes into xzr.
1080 if ((code == kZeroRegCode) && (r31mode == Reg31IsZeroRegister)) {
1081 return;
1082 }
1083
1084 // The template is "# x<code>:value".
1085 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s\n",
1086 clr_reg_name, XRegNameForCode(code, r31mode),
1087 clr_reg_value, reg<uint64_t>(code, r31mode), clr_normal);
1088 }
1089
1090
1091 void Simulator::PrintFPRegister(unsigned code, PrintFPRegisterSizes sizes) {
1092 // The template is "# v<code>:bits (d<code>:value, ...)".
1093
1094 DCHECK(sizes != 0);
1095 DCHECK((sizes & kPrintAllFPRegValues) == sizes);
1096
1097 // Print the raw bits.
1098 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (",
1099 clr_fpreg_name, VRegNameForCode(code),
1100 clr_fpreg_value, fpreg<uint64_t>(code), clr_normal);
1101
1102 // Print all requested value interpretations.
1103 bool need_separator = false;
1104 if (sizes & kPrintDRegValue) {
1105 fprintf(stream_, "%s%s%s: %s%g%s",
1106 need_separator ? ", " : "",
1107 clr_fpreg_name, DRegNameForCode(code),
1108 clr_fpreg_value, fpreg<double>(code), clr_normal);
1109 need_separator = true;
1110 }
1111
1112 if (sizes & kPrintSRegValue) {
1113 fprintf(stream_, "%s%s%s: %s%g%s",
1114 need_separator ? ", " : "",
1115 clr_fpreg_name, SRegNameForCode(code),
1116 clr_fpreg_value, fpreg<float>(code), clr_normal);
1117 need_separator = true;
1118 }
1119
1120 // End the value list.
1121 fprintf(stream_, ")\n");
1122 }
1123
1124
1125 void Simulator::PrintSystemRegister(SystemRegister id) {
1126 switch (id) {
1127 case NZCV:
1128 fprintf(stream_, "# %sNZCV: %sN:%d Z:%d C:%d V:%d%s\n",
1129 clr_flag_name, clr_flag_value,
1130 nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(),
1131 clr_normal);
1132 break;
1133 case FPCR: {
1134 static const char * rmode[] = {
1135 "0b00 (Round to Nearest)",
1136 "0b01 (Round towards Plus Infinity)",
1137 "0b10 (Round towards Minus Infinity)",
1138 "0b11 (Round towards Zero)"
1139 };
1140 DCHECK(fpcr().RMode() < arraysize(rmode));
1088 fprintf(stream_, 1141 fprintf(stream_,
1089 "# %s%4s:%s 0x%016" PRIx64 "%s\n", 1142 "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n",
1090 clr_reg_name, 1143 clr_flag_name, clr_flag_value,
1091 XRegNameForCode(i, Reg31IsStackPointer), 1144 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()],
1092 clr_reg_value,
1093 xreg(i, Reg31IsStackPointer),
1094 clr_normal); 1145 clr_normal);
1146 break;
1095 } 1147 }
1096 // Cache the new register value so the next run can detect any changes. 1148 default:
1097 last_regs[i] = xreg(i, Reg31IsStackPointer); 1149 UNREACHABLE();
1098 } 1150 }
1099 first_run = false; 1151 }
1100 } 1152
1101 1153
1102 1154 void Simulator::PrintRead(uintptr_t address,
1103 void Simulator::PrintFPRegisters(bool print_all_regs) { 1155 size_t size,
1104 static bool first_run = true; 1156 unsigned reg_code) {
1105 static uint64_t last_regs[kNumberOfFPRegisters]; 1157 USE(size); // Size is unused here.
1106 1158
1107 // Print as many rows of registers as necessary, keeping each individual 1159 // The template is "# x<code>:value <- address".
1108 // register in the same column each time (to make it easy to visually scan 1160 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s",
1109 // for changes). 1161 clr_reg_name, XRegNameForCode(reg_code),
1110 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 1162 clr_reg_value, reg<uint64_t>(reg_code), clr_normal);
1111 if (print_all_regs || first_run || (last_regs[i] != dreg_bits(i))) { 1163
1112 fprintf(stream_, 1164 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", 1165 clr_memory_address, address, clr_normal);
1114 clr_fpreg_name, 1166 }
1115 VRegNameForCode(i), 1167
1116 clr_fpreg_value, 1168
1117 dreg_bits(i), 1169 void Simulator::PrintReadFP(uintptr_t address,
1118 clr_normal, 1170 size_t size,
1119 clr_fpreg_name, 1171 unsigned reg_code) {
1120 DRegNameForCode(i), 1172 // The template is "# reg:bits (reg:value) <- address".
1121 clr_fpreg_value, 1173 switch (size) {
1122 dreg(i), 1174 case kSRegSize:
1123 clr_fpreg_name, 1175 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%gf%s)",
1124 SRegNameForCode(i), 1176 clr_fpreg_name, VRegNameForCode(reg_code),
1125 clr_fpreg_value, 1177 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1126 sreg(i), 1178 clr_fpreg_name, SRegNameForCode(reg_code),
1127 clr_normal); 1179 clr_fpreg_value, fpreg<float>(reg_code), clr_normal);
1128 } 1180 break;
1129 // Cache the new register value so the next run can detect any changes. 1181 case kDRegSize:
1130 last_regs[i] = dreg_bits(i); 1182 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)",
1131 } 1183 clr_fpreg_name, VRegNameForCode(reg_code),
1132 first_run = false; 1184 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1133 } 1185 clr_fpreg_name, DRegNameForCode(reg_code),
1134 1186 clr_fpreg_value, fpreg<double>(reg_code), clr_normal);
1135 1187 break;
1136 void Simulator::PrintProcessorState() { 1188 default:
1137 PrintSystemRegisters(); 1189 UNREACHABLE();
1138 PrintRegisters(); 1190 }
1139 PrintFPRegisters(); 1191
1140 } 1192 fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
1141 1193 clr_memory_address, address, clr_normal);
1142 1194 }
1143 void Simulator::PrintWrite(uintptr_t address, uint64_t value, 1195
1144 unsigned num_bytes) { 1196
1145 // The template is "# value -> address". The format string is not used 1197 void Simulator::PrintWrite(uintptr_t address,
1146 // directly in the printf because some compilers struggle with the 1198 size_t size,
1147 // parametrized width field (%0*). 1199 unsigned reg_code) {
1148 const char* format = "# %s0x%0*" PRIx64 "%s -> %s0x%016" PRIxPTR "%s\n"; 1200 // The template is "# reg:value -> address". To keep the trace tidy and
1149 fprintf(stream_, 1201 // readable, the value is aligned with the values in the register trace.
1150 format, 1202 switch (size) {
1151 clr_memory_value, 1203 case kByteSizeInBytes:
1152 num_bytes * 2, // The width in hexadecimal characters. 1204 fprintf(stream_, "# %s%5s<7:0>: %s0x%02" PRIx8 "%s",
1153 value, 1205 clr_reg_name, WRegNameForCode(reg_code),
1154 clr_normal, 1206 clr_reg_value, reg<uint8_t>(reg_code), clr_normal);
1155 clr_memory_address, 1207 break;
1156 address, 1208 case kHalfWordSizeInBytes:
1157 clr_normal); 1209 fprintf(stream_, "# %s%5s<15:0>: %s0x%04" PRIx16 "%s",
1158 } 1210 clr_reg_name, WRegNameForCode(reg_code),
1159 1211 clr_reg_value, reg<uint16_t>(reg_code), clr_normal);
1160 1212 break;
1213 case kWRegSize:
1214 fprintf(stream_, "# %s%5s: %s0x%08" PRIx32 "%s",
1215 clr_reg_name, WRegNameForCode(reg_code),
1216 clr_reg_value, reg<uint32_t>(reg_code), clr_normal);
1217 break;
1218 case kXRegSize:
1219 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s",
1220 clr_reg_name, XRegNameForCode(reg_code),
1221 clr_reg_value, reg<uint64_t>(reg_code), clr_normal);
1222 break;
1223 default:
1224 UNREACHABLE();
1225 }
1226
1227 fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
1228 clr_memory_address, address, clr_normal);
1229 }
1230
1231
1232 void Simulator::PrintWriteFP(uintptr_t address,
1233 size_t size,
1234 unsigned reg_code) {
1235 // The template is "# reg:bits (reg:value) -> address". To keep the trace tidy
1236 // and readable, the value is aligned with the values in the register trace.
1237 switch (size) {
1238 case kSRegSize:
1239 fprintf(stream_, "# %s%5s<31:0>: %s0x%08" PRIx32 "%s (%s%s: %s%gf%s)",
1240 clr_fpreg_name, VRegNameForCode(reg_code),
1241 clr_fpreg_value, fpreg<uint32_t>(reg_code), clr_normal,
1242 clr_fpreg_name, SRegNameForCode(reg_code),
1243 clr_fpreg_value, fpreg<float>(reg_code), clr_normal);
1244 break;
1245 case kDRegSize:
1246 fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)",
1247 clr_fpreg_name, VRegNameForCode(reg_code),
1248 clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1249 clr_fpreg_name, DRegNameForCode(reg_code),
1250 clr_fpreg_value, fpreg<double>(reg_code), clr_normal);
1251 break;
1252 default:
1253 UNREACHABLE();
1254 }
1255
1256 fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
1257 clr_memory_address, address, clr_normal);
1258 }
1259
1260
1161 // Visitors--------------------------------------------------------------------- 1261 // Visitors---------------------------------------------------------------------
1162 1262
1163 void Simulator::VisitUnimplemented(Instruction* instr) { 1263 void Simulator::VisitUnimplemented(Instruction* instr) {
1164 fprintf(stream_, "Unimplemented instruction at %p: 0x%08" PRIx32 "\n", 1264 fprintf(stream_, "Unimplemented instruction at %p: 0x%08" PRIx32 "\n",
1165 reinterpret_cast<void*>(instr), instr->InstructionBits()); 1265 reinterpret_cast<void*>(instr), instr->InstructionBits());
1166 UNIMPLEMENTED(); 1266 UNIMPLEMENTED();
1167 } 1267 }
1168 1268
1169 1269
1170 void Simulator::VisitUnallocated(Instruction* instr) { 1270 void Simulator::VisitUnallocated(Instruction* instr) {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 case EOR: result = op1 ^ op2; break; 1476 case EOR: result = op1 ^ op2; break;
1377 default: 1477 default:
1378 UNIMPLEMENTED(); 1478 UNIMPLEMENTED();
1379 } 1479 }
1380 1480
1381 if (update_flags) { 1481 if (update_flags) {
1382 nzcv().SetN(CalcNFlag(result)); 1482 nzcv().SetN(CalcNFlag(result));
1383 nzcv().SetZ(CalcZFlag(result)); 1483 nzcv().SetZ(CalcZFlag(result));
1384 nzcv().SetC(0); 1484 nzcv().SetC(0);
1385 nzcv().SetV(0); 1485 nzcv().SetV(0);
1486 LogSystemRegister(NZCV);
1386 } 1487 }
1387 1488
1388 set_reg<T>(instr->Rd(), result, instr->RdMode()); 1489 set_reg<T>(instr->Rd(), result, instr->RdMode());
1389 } 1490 }
1390 1491
1391 1492
1392 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { 1493 void Simulator::VisitConditionalCompareRegister(Instruction* instr) {
1393 if (instr->SixtyFourBits()) { 1494 if (instr->SixtyFourBits()) {
1394 ConditionalCompareHelper(instr, xreg(instr->Rm())); 1495 ConditionalCompareHelper(instr, xreg(instr->Rm()));
1395 } else { 1496 } else {
(...skipping 20 matching lines...) Expand all
1416 // the operands. 1517 // the operands.
1417 if (instr->Mask(ConditionalCompareMask) == CCMP) { 1518 if (instr->Mask(ConditionalCompareMask) == CCMP) {
1418 AddWithCarry<T>(true, op1, ~op2, 1); 1519 AddWithCarry<T>(true, op1, ~op2, 1);
1419 } else { 1520 } else {
1420 DCHECK(instr->Mask(ConditionalCompareMask) == CCMN); 1521 DCHECK(instr->Mask(ConditionalCompareMask) == CCMN);
1421 AddWithCarry<T>(true, op1, op2, 0); 1522 AddWithCarry<T>(true, op1, op2, 0);
1422 } 1523 }
1423 } else { 1524 } else {
1424 // If the condition fails, set the status flags to the nzcv immediate. 1525 // If the condition fails, set the status flags to the nzcv immediate.
1425 nzcv().SetFlags(instr->Nzcv()); 1526 nzcv().SetFlags(instr->Nzcv());
1527 LogSystemRegister(NZCV);
1426 } 1528 }
1427 } 1529 }
1428 1530
1429 1531
1430 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) { 1532 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
1431 int offset = instr->ImmLSUnsigned() << instr->SizeLS(); 1533 int offset = instr->ImmLSUnsigned() << instr->SizeLS();
1432 LoadStoreHelper(instr, offset, Offset); 1534 LoadStoreHelper(instr, offset, Offset);
1433 } 1535 }
1434 1536
1435 1537
(...skipping 20 matching lines...) Expand all
1456 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount); 1558 int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount);
1457 LoadStoreHelper(instr, offset, Offset); 1559 LoadStoreHelper(instr, offset, Offset);
1458 } 1560 }
1459 1561
1460 1562
1461 void Simulator::LoadStoreHelper(Instruction* instr, 1563 void Simulator::LoadStoreHelper(Instruction* instr,
1462 int64_t offset, 1564 int64_t offset,
1463 AddrMode addrmode) { 1565 AddrMode addrmode) {
1464 unsigned srcdst = instr->Rt(); 1566 unsigned srcdst = instr->Rt();
1465 unsigned addr_reg = instr->Rn(); 1567 unsigned addr_reg = instr->Rn();
1466 uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode); 1568 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1467 uint8_t* stack = NULL; 1569 uintptr_t stack = 0;
1468 1570
1469 // Handle the writeback for stores before the store. On a CPU the writeback 1571 // 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 1572 // 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 1573 // 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 1574 // 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 1575 // 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 1576 // below ensures that push operations are safe even when interrupted: the
1475 // stack pointer will be decremented before adding an element to the stack. 1577 // stack pointer will be decremented before adding an element to the stack.
1476 if (instr->IsStore()) { 1578 if (instr->IsStore()) {
1477 LoadStoreWriteBack(addr_reg, offset, addrmode); 1579 LoadStoreWriteBack(addr_reg, offset, addrmode);
1478 1580
1479 // For store the address post writeback is used to check access below the 1581 // For store the address post writeback is used to check access below the
1480 // stack. 1582 // stack.
1481 stack = reinterpret_cast<uint8_t*>(sp()); 1583 stack = sp();
1482 } 1584 }
1483 1585
1484 LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask)); 1586 LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask));
1485 switch (op) { 1587 switch (op) {
1486 case LDRB_w: set_wreg(srcdst, MemoryRead<uint8_t>(address)); break; 1588 // Use _no_log variants to suppress the register trace (LOG_REGS,
1487 case LDRH_w: set_wreg(srcdst, MemoryRead<uint16_t>(address)); break; 1589 // LOG_FP_REGS). We will print a more detailed log.
1488 case LDR_w: set_wreg(srcdst, MemoryRead<uint32_t>(address)); break; 1590 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; 1591 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; 1592 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; 1593 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; 1594 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; 1595 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; 1596 case LDRSB_x: set_xreg_no_log(srcdst, MemoryRead<int8_t>(address)); break;
1495 case LDR_s: set_sreg(srcdst, MemoryRead<float>(address)); break; 1597 case LDRSH_x: set_xreg_no_log(srcdst, MemoryRead<int16_t>(address)); break;
1496 case LDR_d: set_dreg(srcdst, MemoryRead<double>(address)); break; 1598 case LDRSW_x: set_xreg_no_log(srcdst, MemoryRead<int32_t>(address)); break;
1599 case LDR_s: set_sreg_no_log(srcdst, MemoryRead<float>(address)); break;
1600 case LDR_d: set_dreg_no_log(srcdst, MemoryRead<double>(address)); break;
1497 1601
1498 case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break; 1602 case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break;
1499 case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break; 1603 case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break;
1500 case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break; 1604 case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break;
1501 case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break; 1605 case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break;
1502 case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break; 1606 case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break;
1503 case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break; 1607 case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break;
1504 1608
1505 default: UNIMPLEMENTED(); 1609 default: UNIMPLEMENTED();
1506 } 1610 }
1507 1611
1612 // Print a detailed trace (including the memory address) instead of the basic
1613 // register:value trace generated by set_*reg().
1614 size_t access_size = 1 << instr->SizeLS();
1615 if (instr->IsLoad()) {
1616 if ((op == LDR_s) || (op == LDR_d)) {
1617 LogReadFP(address, access_size, srcdst);
1618 } else {
1619 LogRead(address, access_size, srcdst);
1620 }
1621 } else {
1622 if ((op == STR_s) || (op == STR_d)) {
1623 LogWriteFP(address, access_size, srcdst);
1624 } else {
1625 LogWrite(address, access_size, srcdst);
1626 }
1627 }
1628
1508 // Handle the writeback for loads after the load to ensure safe pop 1629 // 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 1630 // 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 1631 // 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. 1632 // sp <= fp expected while walking the stack in the sampler.
1512 if (instr->IsLoad()) { 1633 if (instr->IsLoad()) {
1513 // For loads the address pre writeback is used to check access below the 1634 // For loads the address pre writeback is used to check access below the
1514 // stack. 1635 // stack.
1515 stack = reinterpret_cast<uint8_t*>(sp()); 1636 stack = sp();
1516 1637
1517 LoadStoreWriteBack(addr_reg, offset, addrmode); 1638 LoadStoreWriteBack(addr_reg, offset, addrmode);
1518 } 1639 }
1519 1640
1520 // Accesses below the stack pointer (but above the platform stack limit) are 1641 // Accesses below the stack pointer (but above the platform stack limit) are
1521 // not allowed in the ABI. 1642 // not allowed in the ABI.
1522 CheckMemoryAccess(address, stack); 1643 CheckMemoryAccess(address, stack);
1523 } 1644 }
1524 1645
1525 1646
(...skipping 15 matching lines...) Expand all
1541 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) { 1662 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) {
1542 LoadStorePairHelper(instr, Offset); 1663 LoadStorePairHelper(instr, Offset);
1543 } 1664 }
1544 1665
1545 1666
1546 void Simulator::LoadStorePairHelper(Instruction* instr, 1667 void Simulator::LoadStorePairHelper(Instruction* instr,
1547 AddrMode addrmode) { 1668 AddrMode addrmode) {
1548 unsigned rt = instr->Rt(); 1669 unsigned rt = instr->Rt();
1549 unsigned rt2 = instr->Rt2(); 1670 unsigned rt2 = instr->Rt2();
1550 unsigned addr_reg = instr->Rn(); 1671 unsigned addr_reg = instr->Rn();
1551 int offset = instr->ImmLSPair() << instr->SizeLSPair(); 1672 size_t access_size = 1 << instr->SizeLSPair();
1552 uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode); 1673 int64_t offset = instr->ImmLSPair() * access_size;
1553 uint8_t* stack = NULL; 1674 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1675 uintptr_t address2 = address + access_size;
1676 uintptr_t stack = 0;
1554 1677
1555 // Handle the writeback for stores before the store. On a CPU the writeback 1678 // 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 1679 // 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 1680 // 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 1681 // 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 1682 // 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 1683 // below ensures that push operations are safe even when interrupted: the
1561 // stack pointer will be decremented before adding an element to the stack. 1684 // stack pointer will be decremented before adding an element to the stack.
1562 if (instr->IsStore()) { 1685 if (instr->IsStore()) {
1563 LoadStoreWriteBack(addr_reg, offset, addrmode); 1686 LoadStoreWriteBack(addr_reg, offset, addrmode);
1564 1687
1565 // For store the address post writeback is used to check access below the 1688 // For store the address post writeback is used to check access below the
1566 // stack. 1689 // stack.
1567 stack = reinterpret_cast<uint8_t*>(sp()); 1690 stack = sp();
1568 } 1691 }
1569 1692
1570 LoadStorePairOp op = 1693 LoadStorePairOp op =
1571 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); 1694 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask));
1572 1695
1573 // 'rt' and 'rt2' can only be aliased for stores. 1696 // 'rt' and 'rt2' can only be aliased for stores.
1574 DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2)); 1697 DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2));
1575 1698
1576 switch (op) { 1699 switch (op) {
1700 // Use _no_log variants to suppress the register trace (LOG_REGS,
1701 // LOG_FP_REGS). We will print a more detailed log.
1577 case LDP_w: { 1702 case LDP_w: {
1578 set_wreg(rt, MemoryRead<uint32_t>(address)); 1703 DCHECK(access_size == kWRegSize);
1579 set_wreg(rt2, MemoryRead<uint32_t>(address + kWRegSize)); 1704 set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1705 set_wreg_no_log(rt2, MemoryRead<uint32_t>(address2));
1580 break; 1706 break;
1581 } 1707 }
1582 case LDP_s: { 1708 case LDP_s: {
1583 set_sreg(rt, MemoryRead<float>(address)); 1709 DCHECK(access_size == kSRegSize);
1584 set_sreg(rt2, MemoryRead<float>(address + kSRegSize)); 1710 set_sreg_no_log(rt, MemoryRead<float>(address));
1711 set_sreg_no_log(rt2, MemoryRead<float>(address2));
1585 break; 1712 break;
1586 } 1713 }
1587 case LDP_x: { 1714 case LDP_x: {
1588 set_xreg(rt, MemoryRead<uint64_t>(address)); 1715 DCHECK(access_size == kXRegSize);
1589 set_xreg(rt2, MemoryRead<uint64_t>(address + kXRegSize)); 1716 set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1717 set_xreg_no_log(rt2, MemoryRead<uint64_t>(address2));
1590 break; 1718 break;
1591 } 1719 }
1592 case LDP_d: { 1720 case LDP_d: {
1593 set_dreg(rt, MemoryRead<double>(address)); 1721 DCHECK(access_size == kDRegSize);
1594 set_dreg(rt2, MemoryRead<double>(address + kDRegSize)); 1722 set_dreg_no_log(rt, MemoryRead<double>(address));
1723 set_dreg_no_log(rt2, MemoryRead<double>(address2));
1595 break; 1724 break;
1596 } 1725 }
1597 case LDPSW_x: { 1726 case LDPSW_x: {
1598 set_xreg(rt, MemoryRead<int32_t>(address)); 1727 DCHECK(access_size == kWRegSize);
1599 set_xreg(rt2, MemoryRead<int32_t>(address + kWRegSize)); 1728 set_xreg_no_log(rt, MemoryRead<int32_t>(address));
1729 set_xreg_no_log(rt2, MemoryRead<int32_t>(address2));
1600 break; 1730 break;
1601 } 1731 }
1602 case STP_w: { 1732 case STP_w: {
1733 DCHECK(access_size == kWRegSize);
1603 MemoryWrite<uint32_t>(address, wreg(rt)); 1734 MemoryWrite<uint32_t>(address, wreg(rt));
1604 MemoryWrite<uint32_t>(address + kWRegSize, wreg(rt2)); 1735 MemoryWrite<uint32_t>(address2, wreg(rt2));
1605 break; 1736 break;
1606 } 1737 }
1607 case STP_s: { 1738 case STP_s: {
1739 DCHECK(access_size == kSRegSize);
1608 MemoryWrite<float>(address, sreg(rt)); 1740 MemoryWrite<float>(address, sreg(rt));
1609 MemoryWrite<float>(address + kSRegSize, sreg(rt2)); 1741 MemoryWrite<float>(address2, sreg(rt2));
1610 break; 1742 break;
1611 } 1743 }
1612 case STP_x: { 1744 case STP_x: {
1745 DCHECK(access_size == kXRegSize);
1613 MemoryWrite<uint64_t>(address, xreg(rt)); 1746 MemoryWrite<uint64_t>(address, xreg(rt));
1614 MemoryWrite<uint64_t>(address + kXRegSize, xreg(rt2)); 1747 MemoryWrite<uint64_t>(address2, xreg(rt2));
1615 break; 1748 break;
1616 } 1749 }
1617 case STP_d: { 1750 case STP_d: {
1751 DCHECK(access_size == kDRegSize);
1618 MemoryWrite<double>(address, dreg(rt)); 1752 MemoryWrite<double>(address, dreg(rt));
1619 MemoryWrite<double>(address + kDRegSize, dreg(rt2)); 1753 MemoryWrite<double>(address2, dreg(rt2));
1620 break; 1754 break;
1621 } 1755 }
1622 default: UNREACHABLE(); 1756 default: UNREACHABLE();
1623 } 1757 }
1624 1758
1759 // Print a detailed trace (including the memory address) instead of the basic
1760 // register:value trace generated by set_*reg().
1761 if (instr->IsLoad()) {
1762 if ((op == LDP_s) || (op == LDP_d)) {
1763 LogReadFP(address, access_size, rt);
1764 LogReadFP(address2, access_size, rt2);
1765 } else {
1766 LogRead(address, access_size, rt);
1767 LogRead(address2, access_size, rt2);
1768 }
1769 } else {
1770 if ((op == STP_s) || (op == STP_d)) {
1771 LogWriteFP(address, access_size, rt);
1772 LogWriteFP(address2, access_size, rt2);
1773 } else {
1774 LogWrite(address, access_size, rt);
1775 LogWrite(address2, access_size, rt2);
1776 }
1777 }
1778
1625 // Handle the writeback for loads after the load to ensure safe pop 1779 // 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 1780 // 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 1781 // 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. 1782 // sp <= fp expected while walking the stack in the sampler.
1629 if (instr->IsLoad()) { 1783 if (instr->IsLoad()) {
1630 // For loads the address pre writeback is used to check access below the 1784 // For loads the address pre writeback is used to check access below the
1631 // stack. 1785 // stack.
1632 stack = reinterpret_cast<uint8_t*>(sp()); 1786 stack = sp();
1633 1787
1634 LoadStoreWriteBack(addr_reg, offset, addrmode); 1788 LoadStoreWriteBack(addr_reg, offset, addrmode);
1635 } 1789 }
1636 1790
1637 // Accesses below the stack pointer (but above the platform stack limit) are 1791 // Accesses below the stack pointer (but above the platform stack limit) are
1638 // not allowed in the ABI. 1792 // not allowed in the ABI.
1639 CheckMemoryAccess(address, stack); 1793 CheckMemoryAccess(address, stack);
1640 } 1794 }
1641 1795
1642 1796
1643 void Simulator::VisitLoadLiteral(Instruction* instr) { 1797 void Simulator::VisitLoadLiteral(Instruction* instr) {
1644 uint8_t* address = instr->LiteralAddress(); 1798 uintptr_t address = instr->LiteralAddress();
1645 unsigned rt = instr->Rt(); 1799 unsigned rt = instr->Rt();
1646 1800
1647 switch (instr->Mask(LoadLiteralMask)) { 1801 switch (instr->Mask(LoadLiteralMask)) {
1648 case LDR_w_lit: set_wreg(rt, MemoryRead<uint32_t>(address)); break; 1802 // Use _no_log variants to suppress the register trace (LOG_REGS,
1649 case LDR_x_lit: set_xreg(rt, MemoryRead<uint64_t>(address)); break; 1803 // LOG_FP_REGS), then print a more detailed log.
1650 case LDR_s_lit: set_sreg(rt, MemoryRead<float>(address)); break; 1804 case LDR_w_lit:
1651 case LDR_d_lit: set_dreg(rt, MemoryRead<double>(address)); break; 1805 set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1806 LogRead(address, kWRegSize, rt);
1807 break;
1808 case LDR_x_lit:
1809 set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1810 LogRead(address, kXRegSize, rt);
1811 break;
1812 case LDR_s_lit:
1813 set_sreg_no_log(rt, MemoryRead<float>(address));
1814 LogReadFP(address, kSRegSize, rt);
1815 break;
1816 case LDR_d_lit:
1817 set_dreg_no_log(rt, MemoryRead<double>(address));
1818 LogReadFP(address, kDRegSize, rt);
1819 break;
1652 default: UNREACHABLE(); 1820 default: UNREACHABLE();
1653 } 1821 }
1654 } 1822 }
1655 1823
1656 1824
1657 uint8_t* Simulator::LoadStoreAddress(unsigned addr_reg, 1825 uintptr_t Simulator::LoadStoreAddress(unsigned addr_reg, int64_t offset,
1658 int64_t offset, 1826 AddrMode addrmode) {
1659 AddrMode addrmode) {
1660 const unsigned kSPRegCode = kSPRegInternalCode & kRegCodeMask; 1827 const unsigned kSPRegCode = kSPRegInternalCode & kRegCodeMask;
1661 int64_t address = xreg(addr_reg, Reg31IsStackPointer); 1828 uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1662 if ((addr_reg == kSPRegCode) && ((address % 16) != 0)) { 1829 if ((addr_reg == kSPRegCode) && ((address % 16) != 0)) {
1663 // When the base register is SP the stack pointer is required to be 1830 // When the base register is SP the stack pointer is required to be
1664 // quadword aligned prior to the address calculation and write-backs. 1831 // quadword aligned prior to the address calculation and write-backs.
1665 // Misalignment will cause a stack alignment fault. 1832 // Misalignment will cause a stack alignment fault.
1666 FATAL("ALIGNMENT EXCEPTION"); 1833 FATAL("ALIGNMENT EXCEPTION");
1667 } 1834 }
1668 1835
1669 if ((addrmode == Offset) || (addrmode == PreIndex)) { 1836 if ((addrmode == Offset) || (addrmode == PreIndex)) {
1670 address += offset; 1837 address += offset;
1671 } 1838 }
1672 1839
1673 return reinterpret_cast<uint8_t*>(address); 1840 return address;
1674 } 1841 }
1675 1842
1676 1843
1677 void Simulator::LoadStoreWriteBack(unsigned addr_reg, 1844 void Simulator::LoadStoreWriteBack(unsigned addr_reg,
1678 int64_t offset, 1845 int64_t offset,
1679 AddrMode addrmode) { 1846 AddrMode addrmode) {
1680 if ((addrmode == PreIndex) || (addrmode == PostIndex)) { 1847 if ((addrmode == PreIndex) || (addrmode == PostIndex)) {
1681 DCHECK(offset != 0); 1848 DCHECK(offset != 0);
1682 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 1849 uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1683 set_reg(addr_reg, address + offset, Reg31IsStackPointer); 1850 set_reg(addr_reg, address + offset, Reg31IsStackPointer);
1684 } 1851 }
1685 } 1852 }
1686 1853
1687 1854
1688 void Simulator::CheckMemoryAccess(uint8_t* address, uint8_t* stack) { 1855 void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) {
1689 if ((address >= stack_limit_) && (address < stack)) { 1856 if ((address >= stack_limit_) && (address < stack)) {
1690 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n"); 1857 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n");
1691 fprintf(stream_, " sp is here: 0x%16p\n", stack); 1858 fprintf(stream_, " sp is here: 0x%016" PRIx64 "\n", stack);
1692 fprintf(stream_, " access was here: 0x%16p\n", address); 1859 fprintf(stream_, " access was here: 0x%016" PRIx64 "\n", address);
1693 fprintf(stream_, " stack limit is here: 0x%16p\n", stack_limit_); 1860 fprintf(stream_, " stack limit is here: 0x%016" PRIx64 "\n", stack_limit_);
1694 fprintf(stream_, "\n"); 1861 fprintf(stream_, "\n");
1695 FATAL("ACCESS BELOW STACK POINTER"); 1862 FATAL("ACCESS BELOW STACK POINTER");
1696 } 1863 }
1697 } 1864 }
1698 1865
1699 1866
1700 void Simulator::VisitMoveWideImmediate(Instruction* instr) { 1867 void Simulator::VisitMoveWideImmediate(Instruction* instr) {
1701 MoveWideImmediateOp mov_op = 1868 MoveWideImmediateOp mov_op =
1702 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); 1869 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
1703 int64_t new_xn_val = 0; 1870 int64_t new_xn_val = 0;
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2238 case FCCMP_d: { 2405 case FCCMP_d: {
2239 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 2406 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
2240 // If the condition passes, set the status flags to the result of 2407 // If the condition passes, set the status flags to the result of
2241 // comparing the operands. 2408 // comparing the operands.
2242 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits 2409 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits
2243 : kSRegSizeInBits; 2410 : kSRegSizeInBits;
2244 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm())); 2411 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm()));
2245 } else { 2412 } else {
2246 // If the condition fails, set the status flags to the nzcv immediate. 2413 // If the condition fails, set the status flags to the nzcv immediate.
2247 nzcv().SetFlags(instr->Nzcv()); 2414 nzcv().SetFlags(instr->Nzcv());
2415 LogSystemRegister(NZCV);
2248 } 2416 }
2249 break; 2417 break;
2250 } 2418 }
2251 default: UNIMPLEMENTED(); 2419 default: UNIMPLEMENTED();
2252 } 2420 }
2253 } 2421 }
2254 2422
2255 2423
2256 void Simulator::VisitFPConditionalSelect(Instruction* instr) { 2424 void Simulator::VisitFPConditionalSelect(Instruction* instr) {
2257 AssertSupportedFPCR(); 2425 AssertSupportedFPCR();
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 case MRS: { 3188 case MRS: {
3021 switch (instr->ImmSystemRegister()) { 3189 switch (instr->ImmSystemRegister()) {
3022 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break; 3190 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break;
3023 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break; 3191 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break;
3024 default: UNIMPLEMENTED(); 3192 default: UNIMPLEMENTED();
3025 } 3193 }
3026 break; 3194 break;
3027 } 3195 }
3028 case MSR: { 3196 case MSR: {
3029 switch (instr->ImmSystemRegister()) { 3197 switch (instr->ImmSystemRegister()) {
3030 case NZCV: nzcv().SetRawValue(xreg(instr->Rt())); break; 3198 case NZCV:
3031 case FPCR: fpcr().SetRawValue(xreg(instr->Rt())); break; 3199 nzcv().SetRawValue(xreg(instr->Rt()));
3200 LogSystemRegister(NZCV);
3201 break;
3202 case FPCR:
3203 fpcr().SetRawValue(xreg(instr->Rt()));
3204 LogSystemRegister(FPCR);
3205 break;
3032 default: UNIMPLEMENTED(); 3206 default: UNIMPLEMENTED();
3033 } 3207 }
3034 break; 3208 break;
3035 } 3209 }
3036 } 3210 }
3037 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 3211 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
3038 DCHECK(instr->Mask(SystemHintMask) == HINT); 3212 DCHECK(instr->Mask(SystemHintMask) == HINT);
3039 switch (instr->ImmHint()) { 3213 switch (instr->ImmHint()) {
3040 case NOP: break; 3214 case NOP: break;
3041 default: UNIMPLEMENTED(); 3215 default: UNIMPLEMENTED();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3232 3406
3233 // Disassemble. 3407 // Disassemble.
3234 PrintInstructionsAt(reinterpret_cast<Instruction*>(address), 3408 PrintInstructionsAt(reinterpret_cast<Instruction*>(address),
3235 n_of_instrs_to_disasm); 3409 n_of_instrs_to_disasm);
3236 PrintF("\n"); 3410 PrintF("\n");
3237 3411
3238 // print / p ------------------------------------------------------------- 3412 // print / p -------------------------------------------------------------
3239 } else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) { 3413 } else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) {
3240 if (argc == 2) { 3414 if (argc == 2) {
3241 if (strcmp(arg1, "all") == 0) { 3415 if (strcmp(arg1, "all") == 0) {
3242 PrintRegisters(true); 3416 PrintRegisters();
3243 PrintFPRegisters(true); 3417 PrintFPRegisters();
3244 } else { 3418 } else {
3245 if (!PrintValue(arg1)) { 3419 if (!PrintValue(arg1)) {
3246 PrintF("%s unrecognized\n", arg1); 3420 PrintF("%s unrecognized\n", arg1);
3247 } 3421 }
3248 } 3422 }
3249 } else { 3423 } else {
3250 PrintF( 3424 PrintF(
3251 "print <register>\n" 3425 "print <register>\n"
3252 " Print the content of a register. (alias 'p')\n" 3426 " Print the content of a register. (alias 'p')\n"
3253 " 'print all' will print all registers.\n" 3427 " 'print all' will print all registers.\n"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
3437 char const *message = 3611 char const *message =
3438 reinterpret_cast<char const*>( 3612 reinterpret_cast<char const*>(
3439 pc_->InstructionAtOffset(kDebugMessageOffset)); 3613 pc_->InstructionAtOffset(kDebugMessageOffset));
3440 3614
3441 // Always print something when we hit a debug point that breaks. 3615 // 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 3616 // We are going to break, so printing something is not an issue in
3443 // terms of speed. 3617 // terms of speed.
3444 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) { 3618 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) {
3445 if (message != NULL) { 3619 if (message != NULL) {
3446 PrintF(stream_, 3620 PrintF(stream_,
3447 "%sDebugger hit %d: %s%s%s\n", 3621 "# %sDebugger hit %d: %s%s%s\n",
3448 clr_debug_number, 3622 clr_debug_number,
3449 code, 3623 code,
3450 clr_debug_message, 3624 clr_debug_message,
3451 message, 3625 message,
3452 clr_normal); 3626 clr_normal);
3453 } else { 3627 } else {
3454 PrintF(stream_, 3628 PrintF(stream_,
3455 "%sDebugger hit %d.%s\n", 3629 "# %sDebugger hit %d.%s\n",
3456 clr_debug_number, 3630 clr_debug_number,
3457 code, 3631 code,
3458 clr_normal); 3632 clr_normal);
3459 } 3633 }
3460 } 3634 }
3461 3635
3462 // Other options. 3636 // Other options.
3463 switch (parameters & kDebuggerTracingDirectivesMask) { 3637 switch (parameters & kDebuggerTracingDirectivesMask) {
3464 case TRACE_ENABLE: 3638 case TRACE_ENABLE:
3465 set_log_parameters(log_parameters() | parameters); 3639 set_log_parameters(log_parameters() | parameters);
3466 if (parameters & LOG_SYS_REGS) { PrintSystemRegisters(); } 3640 if (parameters & LOG_SYS_REGS) { PrintSystemRegisters(); }
3467 if (parameters & LOG_REGS) { PrintRegisters(); } 3641 if (parameters & LOG_REGS) { PrintRegisters(); }
3468 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); } 3642 if (parameters & LOG_FP_REGS) { PrintFPRegisters(); }
3469 break; 3643 break;
3470 case TRACE_DISABLE: 3644 case TRACE_DISABLE:
3471 set_log_parameters(log_parameters() & ~parameters); 3645 set_log_parameters(log_parameters() & ~parameters);
3472 break; 3646 break;
3473 case TRACE_OVERRIDE: 3647 case TRACE_OVERRIDE:
3474 set_log_parameters(parameters); 3648 set_log_parameters(parameters);
3475 break; 3649 break;
3476 default: 3650 default:
3477 // We don't support a one-shot LOG_DISASM. 3651 // We don't support a one-shot LOG_DISASM.
3478 DCHECK((parameters & LOG_DISASM) == 0); 3652 DCHECK((parameters & LOG_DISASM) == 0);
3479 // Don't print information that is already being traced. 3653 // Don't print information that is already being traced.
3480 parameters &= ~log_parameters(); 3654 parameters &= ~log_parameters();
3481 // Print the requested information. 3655 // Print the requested information.
3482 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true); 3656 if (parameters & LOG_SYS_REGS) PrintSystemRegisters();
3483 if (parameters & LOG_REGS) PrintRegisters(true); 3657 if (parameters & LOG_REGS) PrintRegisters();
3484 if (parameters & LOG_FP_REGS) PrintFPRegisters(true); 3658 if (parameters & LOG_FP_REGS) PrintFPRegisters();
3485 } 3659 }
3486 3660
3487 // The stop parameters are inlined in the code. Skip them: 3661 // The stop parameters are inlined in the code. Skip them:
3488 // - Skip to the end of the message string. 3662 // - Skip to the end of the message string.
3489 size_t size = kDebugMessageOffset + strlen(message) + 1; 3663 size_t size = kDebugMessageOffset + strlen(message) + 1;
3490 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize)); 3664 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize));
3491 // - Verify that the unreachable marker is present. 3665 // - Verify that the unreachable marker is present.
3492 DCHECK(pc_->Mask(ExceptionMask) == HLT); 3666 DCHECK(pc_->Mask(ExceptionMask) == HLT);
3493 DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable); 3667 DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable);
3494 // - Skip past the unreachable marker. 3668 // - Skip past the unreachable marker.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 3817
3644 delete[] format; 3818 delete[] format;
3645 } 3819 }
3646 3820
3647 3821
3648 #endif // USE_SIMULATOR 3822 #endif // USE_SIMULATOR
3649 3823
3650 } } // namespace v8::internal 3824 } } // namespace v8::internal
3651 3825
3652 #endif // V8_TARGET_ARCH_ARM64 3826 #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