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

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

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