OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 PrintF("Hit and disabled a breakpoint at %p.\n", | 800 PrintF("Hit and disabled a breakpoint at %p.\n", |
801 reinterpret_cast<void*>(pc_)); | 801 reinterpret_cast<void*>(pc_)); |
802 Debug(); | 802 Debug(); |
803 } | 803 } |
804 } | 804 } |
805 | 805 |
806 | 806 |
807 void Simulator::CheckBreakNext() { | 807 void Simulator::CheckBreakNext() { |
808 // If the current instruction is a BL, insert a breakpoint just after it. | 808 // If the current instruction is a BL, insert a breakpoint just after it. |
809 if (break_on_next_ && pc_->IsBranchAndLinkToRegister()) { | 809 if (break_on_next_ && pc_->IsBranchAndLinkToRegister()) { |
810 SetBreakpoint(pc_->NextInstruction()); | 810 SetBreakpoint(pc_->following()); |
811 break_on_next_ = false; | 811 break_on_next_ = false; |
812 } | 812 } |
813 } | 813 } |
814 | 814 |
815 | 815 |
816 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) { | 816 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) { |
817 Instruction* end = start->InstructionAtOffset(count * kInstructionSize); | 817 Instruction* end = start->InstructionAtOffset(count * kInstructionSize); |
818 for (Instruction* pc = start; pc < end; pc = pc->NextInstruction()) { | 818 for (Instruction* pc = start; pc < end; pc = pc->following()) { |
819 disassembler_decoder_->Decode(pc); | 819 disassembler_decoder_->Decode(pc); |
820 } | 820 } |
821 } | 821 } |
822 | 822 |
823 | 823 |
824 void Simulator::PrintSystemRegisters(bool print_all) { | 824 void Simulator::PrintSystemRegisters(bool print_all) { |
825 static bool first_run = true; | 825 static bool first_run = true; |
826 | 826 |
827 // Define some colour codes to use for the register dump. | 827 // Define some colour codes to use for the register dump. |
828 // TODO(jbramley): Find a more elegant way of defining these. | 828 // TODO(jbramley): Find a more elegant way of defining these. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 default: | 989 default: |
990 UNREACHABLE(); | 990 UNREACHABLE(); |
991 break; | 991 break; |
992 } | 992 } |
993 } | 993 } |
994 | 994 |
995 | 995 |
996 void Simulator::VisitUnconditionalBranch(Instruction* instr) { | 996 void Simulator::VisitUnconditionalBranch(Instruction* instr) { |
997 switch (instr->Mask(UnconditionalBranchMask)) { | 997 switch (instr->Mask(UnconditionalBranchMask)) { |
998 case BL: | 998 case BL: |
999 set_lr(instr->NextInstruction()); | 999 set_lr(instr->following()); |
1000 // Fall through. | 1000 // Fall through. |
1001 case B: | 1001 case B: |
1002 set_pc(instr->ImmPCOffsetTarget()); | 1002 set_pc(instr->ImmPCOffsetTarget()); |
1003 break; | 1003 break; |
1004 default: | 1004 default: |
1005 UNREACHABLE(); | 1005 UNREACHABLE(); |
1006 } | 1006 } |
1007 } | 1007 } |
1008 | 1008 |
1009 | 1009 |
1010 void Simulator::VisitConditionalBranch(Instruction* instr) { | 1010 void Simulator::VisitConditionalBranch(Instruction* instr) { |
1011 ASSERT(instr->Mask(ConditionalBranchMask) == B_cond); | 1011 ASSERT(instr->Mask(ConditionalBranchMask) == B_cond); |
1012 if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) { | 1012 if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) { |
1013 set_pc(instr->ImmPCOffsetTarget()); | 1013 set_pc(instr->ImmPCOffsetTarget()); |
1014 } | 1014 } |
1015 } | 1015 } |
1016 | 1016 |
1017 | 1017 |
1018 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) { | 1018 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) { |
1019 Instruction* target = reg<Instruction*>(instr->Rn()); | 1019 Instruction* target = reg<Instruction*>(instr->Rn()); |
1020 switch (instr->Mask(UnconditionalBranchToRegisterMask)) { | 1020 switch (instr->Mask(UnconditionalBranchToRegisterMask)) { |
1021 case BLR: { | 1021 case BLR: { |
1022 set_lr(instr->NextInstruction()); | 1022 set_lr(instr->following()); |
1023 if (instr->Rn() == 31) { | 1023 if (instr->Rn() == 31) { |
1024 // BLR XZR is used as a guard for the constant pool. We should never hit | 1024 // BLR XZR is used as a guard for the constant pool. We should never hit |
1025 // this, but if we do trap to allow debugging. | 1025 // this, but if we do trap to allow debugging. |
1026 Debug(); | 1026 Debug(); |
1027 } | 1027 } |
1028 // Fall through. | 1028 // Fall through. |
1029 } | 1029 } |
1030 case BR: | 1030 case BR: |
1031 case RET: set_pc(target); break; | 1031 case RET: set_pc(target); break; |
1032 default: UNIMPLEMENTED(); | 1032 default: UNIMPLEMENTED(); |
(...skipping 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3355 : (""); | 3355 : (""); |
3356 char const* const clr_printf = (FLAG_log_colour) ? ("\033[0;32m") | 3356 char const* const clr_printf = (FLAG_log_colour) ? ("\033[0;32m") |
3357 : (""); | 3357 : (""); |
3358 | 3358 |
3359 switch (instr->Mask(ExceptionMask)) { | 3359 switch (instr->Mask(ExceptionMask)) { |
3360 case HLT: { | 3360 case HLT: { |
3361 if (instr->ImmException() == kImmExceptionIsDebug) { | 3361 if (instr->ImmException() == kImmExceptionIsDebug) { |
3362 // Read the arguments encoded inline in the instruction stream. | 3362 // Read the arguments encoded inline in the instruction stream. |
3363 uint32_t code; | 3363 uint32_t code; |
3364 uint32_t parameters; | 3364 uint32_t parameters; |
3365 char const * message; | |
3366 | 3365 |
3367 ASSERT(sizeof(*pc_) == 1); | 3366 memcpy(&code, |
3368 memcpy(&code, pc_ + kDebugCodeOffset, sizeof(code)); | 3367 pc_->InstructionAtOffset(kDebugCodeOffset), |
3369 memcpy(¶meters, pc_ + kDebugParamsOffset, sizeof(parameters)); | 3368 sizeof(code)); |
3370 message = reinterpret_cast<char const *>(pc_ + kDebugMessageOffset); | 3369 memcpy(¶meters, |
| 3370 pc_->InstructionAtOffset(kDebugParamsOffset), |
| 3371 sizeof(parameters)); |
| 3372 char const *message = |
| 3373 reinterpret_cast<char const*>( |
| 3374 pc_->InstructionAtOffset(kDebugMessageOffset)); |
3371 | 3375 |
3372 // Always print something when we hit a debug point that breaks. | 3376 // Always print something when we hit a debug point that breaks. |
3373 // We are going to break, so printing something is not an issue in | 3377 // We are going to break, so printing something is not an issue in |
3374 // terms of speed. | 3378 // terms of speed. |
3375 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) { | 3379 if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) { |
3376 if (message != NULL) { | 3380 if (message != NULL) { |
3377 PrintF("%sDebugger hit %d: %s%s%s\n", | 3381 PrintF("%sDebugger hit %d: %s%s%s\n", |
3378 clr_debug_number, | 3382 clr_debug_number, |
3379 code, | 3383 code, |
3380 clr_debug_message, | 3384 clr_debug_message, |
(...skipping 27 matching lines...) Expand all Loading... |
3408 // Don't print information that is already being traced. | 3412 // Don't print information that is already being traced. |
3409 parameters &= ~log_parameters(); | 3413 parameters &= ~log_parameters(); |
3410 // Print the requested information. | 3414 // Print the requested information. |
3411 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true); | 3415 if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true); |
3412 if (parameters & LOG_REGS) PrintRegisters(true); | 3416 if (parameters & LOG_REGS) PrintRegisters(true); |
3413 if (parameters & LOG_FP_REGS) PrintFPRegisters(true); | 3417 if (parameters & LOG_FP_REGS) PrintFPRegisters(true); |
3414 } | 3418 } |
3415 | 3419 |
3416 // The stop parameters are inlined in the code. Skip them: | 3420 // The stop parameters are inlined in the code. Skip them: |
3417 // - Skip to the end of the message string. | 3421 // - Skip to the end of the message string. |
3418 pc_ += kDebugMessageOffset + strlen(message) + 1; | 3422 size_t size = kDebugMessageOffset + strlen(message) + 1; |
3419 // - Advance to the next aligned location. | 3423 pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize)); |
3420 pc_ = AlignUp(pc_, kInstructionSize); | |
3421 // - Verify that the unreachable marker is present. | 3424 // - Verify that the unreachable marker is present. |
3422 ASSERT(pc_->Mask(ExceptionMask) == HLT); | 3425 ASSERT(pc_->Mask(ExceptionMask) == HLT); |
3423 ASSERT(pc_->ImmException() == kImmExceptionIsUnreachable); | 3426 ASSERT(pc_->ImmException() == kImmExceptionIsUnreachable); |
3424 // - Skip past the unreachable marker. | 3427 // - Skip past the unreachable marker. |
3425 set_pc(pc_->NextInstruction()); | 3428 set_pc(pc_->following()); |
3426 | 3429 |
3427 // Check if the debugger should break. | 3430 // Check if the debugger should break. |
3428 if (parameters & BREAK) Debug(); | 3431 if (parameters & BREAK) Debug(); |
3429 | 3432 |
3430 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) { | 3433 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) { |
3431 // TODO(all): Extract the call redirection code into a separate | 3434 // TODO(all): Extract the call redirection code into a separate |
3432 // function. | 3435 // function. |
3433 | 3436 |
3434 Redirection* redirection = Redirection::FromHltInstruction(instr); | 3437 Redirection* redirection = Redirection::FromHltInstruction(instr); |
3435 | 3438 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3608 #endif | 3611 #endif |
3609 break; | 3612 break; |
3610 } | 3613 } |
3611 } | 3614 } |
3612 | 3615 |
3613 set_lr(return_address); | 3616 set_lr(return_address); |
3614 set_pc(return_address); | 3617 set_pc(return_address); |
3615 } else if (instr->ImmException() == kImmExceptionIsPrintf) { | 3618 } else if (instr->ImmException() == kImmExceptionIsPrintf) { |
3616 // Read the argument encoded inline in the instruction stream. | 3619 // Read the argument encoded inline in the instruction stream. |
3617 uint32_t type; | 3620 uint32_t type; |
3618 ASSERT(sizeof(*pc_) == 1); | 3621 memcpy(&type, |
3619 memcpy(&type, pc_ + kPrintfTypeOffset, sizeof(type)); | 3622 pc_->InstructionAtOffset(kPrintfTypeOffset), |
| 3623 sizeof(type)); |
3620 | 3624 |
3621 const char* format = reg<const char*>(0); | 3625 const char* format = reg<const char*>(0); |
3622 | 3626 |
3623 // Pass all of the relevant PCS registers onto printf. It doesn't | 3627 // Pass all of the relevant PCS registers onto printf. It doesn't |
3624 // matter if we pass too many as the extra ones won't be read. | 3628 // matter if we pass too many as the extra ones won't be read. |
3625 int result; | 3629 int result; |
3626 fputs(clr_printf, stream_); | 3630 fputs(clr_printf, stream_); |
3627 if (type == CPURegister::kRegister) { | 3631 if (type == CPURegister::kRegister) { |
3628 result = fprintf(stream_, format, | 3632 result = fprintf(stream_, format, |
3629 xreg(1), xreg(2), xreg(3), xreg(4), | 3633 xreg(1), xreg(2), xreg(3), xreg(4), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3661 default: | 3665 default: |
3662 UNIMPLEMENTED(); | 3666 UNIMPLEMENTED(); |
3663 } | 3667 } |
3664 } | 3668 } |
3665 | 3669 |
3666 #endif // USE_SIMULATOR | 3670 #endif // USE_SIMULATOR |
3667 | 3671 |
3668 } } // namespace v8::internal | 3672 } } // namespace v8::internal |
3669 | 3673 |
3670 #endif // V8_TARGET_ARCH_A64 | 3674 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |