OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <limits.h> | 5 #include <limits.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #if V8_TARGET_ARCH_MIPS | 10 #if V8_TARGET_ARCH_MIPS |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // Overwrite the instruction and address with nops. | 122 // Overwrite the instruction and address with nops. |
123 instr->SetInstructionBits(kNopInstr); | 123 instr->SetInstructionBits(kNopInstr); |
124 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); | 124 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); |
125 } | 125 } |
126 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize); | 126 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize); |
127 } | 127 } |
128 | 128 |
129 | 129 |
130 #else // GENERATED_CODE_COVERAGE | 130 #else // GENERATED_CODE_COVERAGE |
131 | 131 |
132 #define UNSUPPORTED() printf("Unsupported instruction.\n"); | 132 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n"); |
133 | 133 |
134 static void InitializeCoverage() {} | 134 static void InitializeCoverage() {} |
135 | 135 |
136 | 136 |
137 void MipsDebugger::Stop(Instruction* instr) { | 137 void MipsDebugger::Stop(Instruction* instr) { |
138 // Get the stop code. | 138 // Get the stop code. |
139 uint32_t code = instr->Bits(25, 6); | 139 uint32_t code = instr->Bits(25, 6); |
140 // Retrieve the encoded address, which comes just after this stop. | 140 // Retrieve the encoded address, which comes just after this stop. |
141 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + | 141 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + |
142 Instruction::kInstrSize); | 142 Instruction::kInstrSize); |
(...skipping 3586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3729 break; | 3729 break; |
3730 case SPECIAL3: | 3730 case SPECIAL3: |
3731 DecodeTypeRegisterSPECIAL3(); | 3731 DecodeTypeRegisterSPECIAL3(); |
3732 break; | 3732 break; |
3733 default: | 3733 default: |
3734 UNREACHABLE(); | 3734 UNREACHABLE(); |
3735 } | 3735 } |
3736 } | 3736 } |
3737 | 3737 |
3738 | 3738 |
3739 // Branch instructions common part. | 3739 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). |
3740 #define BranchAndLinkHelper(do_branch) \ | |
3741 execute_branch_delay_instruction = true; \ | |
3742 if (do_branch) { \ | |
3743 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; \ | |
3744 set_register(31, current_pc + 2 * Instruction::kInstrSize); \ | |
3745 } else { \ | |
3746 next_pc = current_pc + 2 * Instruction::kInstrSize; \ | |
3747 } | |
3748 | |
3749 #define BranchHelper(do_branch) \ | |
3750 execute_branch_delay_instruction = true; \ | |
3751 if (do_branch) { \ | |
3752 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; \ | |
3753 } else { \ | |
3754 next_pc = current_pc + 2 * Instruction::kInstrSize; \ | |
3755 } | |
3756 | |
3757 | |
3758 // Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq). | |
3759 void Simulator::DecodeTypeImmediate(Instruction* instr) { | 3740 void Simulator::DecodeTypeImmediate(Instruction* instr) { |
3760 // Instruction fields. | 3741 // Instruction fields. |
3761 Opcode op = instr->OpcodeFieldRaw(); | 3742 Opcode op = instr->OpcodeFieldRaw(); |
3762 int32_t rs_reg = instr->RsValue(); | 3743 int32_t rs_reg = instr->RsValue(); |
3763 int32_t rs = get_register(instr->RsValue()); | 3744 int32_t rs = get_register(instr->RsValue()); |
3764 uint32_t rs_u = static_cast<uint32_t>(rs); | 3745 uint32_t rs_u = static_cast<uint32_t>(rs); |
3765 int32_t rt_reg = instr->RtValue(); // Destination register. | 3746 int32_t rt_reg = instr->RtValue(); // Destination register. |
3766 int32_t rt = get_register(rt_reg); | 3747 int32_t rt = get_register(rt_reg); |
3767 int16_t imm16 = instr->Imm16Value(); | 3748 int16_t imm16 = instr->Imm16Value(); |
3768 int32_t imm21 = instr->Imm21Value(); | |
3769 int32_t imm26 = instr->Imm26Value(); | |
3770 | 3749 |
3771 int32_t ft_reg = instr->FtValue(); // Destination register. | 3750 int32_t ft_reg = instr->FtValue(); // Destination register. |
3772 int64_t ft; | |
3773 | 3751 |
3774 // Zero extended immediate. | 3752 // Zero extended immediate. |
3775 uint32_t oe_imm16 = 0xffff & imm16; | 3753 uint32_t oe_imm16 = 0xffff & imm16; |
3776 // Sign extended immediate. | 3754 // Sign extended immediate. |
3777 int32_t se_imm16 = imm16; | 3755 int32_t se_imm16 = imm16; |
3778 int32_t se_imm26 = imm26 | ((imm26 & 0x2000000) ? 0xfc000000 : 0); | |
3779 | 3756 |
3780 // Get current pc. | |
3781 int32_t current_pc = get_pc(); | |
3782 // Next pc. | 3757 // Next pc. |
3783 int32_t next_pc = bad_ra; | 3758 int32_t next_pc = bad_ra; |
3784 | 3759 |
3785 // Used for conditional branch instructions. | 3760 // Used for conditional branch instructions. |
3786 bool execute_branch_delay_instruction = false; | 3761 bool execute_branch_delay_instruction = false; |
3787 | 3762 |
3788 // Used for arithmetic instructions. | 3763 // Used for arithmetic instructions. |
3789 int32_t alu_out = 0; | 3764 int32_t alu_out = 0; |
3790 | 3765 |
3791 // Used for memory instructions. | 3766 // Used for memory instructions. |
3792 int32_t addr = 0x0; | 3767 int32_t addr = 0x0; |
3793 | 3768 |
3794 // ---------- Configuration (and execution for REGIMM). | 3769 // Branch instructions common part. |
| 3770 auto BranchAndLinkHelper = [this, instr, &next_pc, |
| 3771 &execute_branch_delay_instruction]( |
| 3772 bool do_branch) { |
| 3773 execute_branch_delay_instruction = true; |
| 3774 int32_t current_pc = get_pc(); |
| 3775 if (do_branch) { |
| 3776 int16_t imm16 = instr->Imm16Value(); |
| 3777 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| 3778 set_register(31, current_pc + 2 * Instruction::kInstrSize); |
| 3779 } else { |
| 3780 next_pc = current_pc + 2 * Instruction::kInstrSize; |
| 3781 } |
| 3782 }; |
| 3783 |
| 3784 auto BranchHelper = [this, instr, &next_pc, |
| 3785 &execute_branch_delay_instruction](bool do_branch) { |
| 3786 execute_branch_delay_instruction = true; |
| 3787 int32_t current_pc = get_pc(); |
| 3788 if (do_branch) { |
| 3789 int16_t imm16 = instr->Imm16Value(); |
| 3790 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| 3791 } else { |
| 3792 next_pc = current_pc + 2 * Instruction::kInstrSize; |
| 3793 } |
| 3794 }; |
| 3795 |
| 3796 auto BranchAndLinkCompactHelper = [this, instr, &next_pc](bool do_branch, |
| 3797 int bits) { |
| 3798 int32_t current_pc = get_pc(); |
| 3799 CheckForbiddenSlot(current_pc); |
| 3800 if (do_branch) { |
| 3801 int32_t imm = instr->ImmValue(bits); |
| 3802 imm <<= 32 - bits; |
| 3803 imm >>= 32 - bits; |
| 3804 next_pc = current_pc + (imm << 2) + Instruction::kInstrSize; |
| 3805 set_register(31, current_pc + Instruction::kInstrSize); |
| 3806 } |
| 3807 }; |
| 3808 |
| 3809 auto BranchCompactHelper = [&next_pc, this, instr](bool do_branch, int bits) { |
| 3810 int32_t current_pc = get_pc(); |
| 3811 CheckForbiddenSlot(current_pc); |
| 3812 if (do_branch) { |
| 3813 int32_t imm = instr->ImmValue(bits); |
| 3814 imm <<= 32 - bits; |
| 3815 imm >>= 32 - bits; |
| 3816 next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize; |
| 3817 } |
| 3818 }; |
| 3819 |
| 3820 |
3795 switch (op) { | 3821 switch (op) { |
3796 // ------------- COP1. Coprocessor instructions. | 3822 // ------------- COP1. Coprocessor instructions. |
3797 case COP1: | 3823 case COP1: |
3798 switch (instr->RsFieldRaw()) { | 3824 switch (instr->RsFieldRaw()) { |
3799 case BC1: { // Branch on coprocessor condition. | 3825 case BC1: { // Branch on coprocessor condition. |
3800 // Floating point. | 3826 // Floating point. |
3801 uint32_t cc = instr->FBccValue(); | 3827 uint32_t cc = instr->FBccValue(); |
3802 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); | 3828 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); |
3803 uint32_t cc_value = test_fcsr_bit(fcsr_cc); | 3829 uint32_t cc_value = test_fcsr_bit(fcsr_cc); |
3804 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; | 3830 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; |
3805 execute_branch_delay_instruction = true; | 3831 BranchHelper(do_branch); |
3806 // Set next_pc. | |
3807 if (do_branch) { | |
3808 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | |
3809 } else { | |
3810 next_pc = current_pc + kBranchReturnOffset; | |
3811 } | |
3812 break; | 3832 break; |
3813 } | 3833 } |
3814 case BC1EQZ: | 3834 case BC1EQZ: |
3815 ft = get_fpu_register(ft_reg); | 3835 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); |
3816 execute_branch_delay_instruction = true; | |
3817 // Set next_pc. | |
3818 if (!(ft & 0x1)) { | |
3819 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | |
3820 } else { | |
3821 next_pc = current_pc + kBranchReturnOffset; | |
3822 } | |
3823 break; | 3836 break; |
3824 case BC1NEZ: | 3837 case BC1NEZ: |
3825 ft = get_fpu_register(ft_reg); | 3838 BranchHelper(get_fpu_register(ft_reg) & 0x1); |
3826 execute_branch_delay_instruction = true; | |
3827 // Set next_pc. | |
3828 if (ft & 0x1) { | |
3829 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | |
3830 } else { | |
3831 next_pc = current_pc + kBranchReturnOffset; | |
3832 } | |
3833 break; | 3839 break; |
3834 default: | 3840 default: |
3835 UNREACHABLE(); | 3841 UNREACHABLE(); |
3836 } | 3842 } |
3837 break; | 3843 break; |
3838 // ------------- REGIMM class. | 3844 // ------------- REGIMM class. |
3839 case REGIMM: | 3845 case REGIMM: |
3840 switch (instr->RtFieldRaw()) { | 3846 switch (instr->RtFieldRaw()) { |
3841 case BLTZ: | 3847 case BLTZ: |
3842 BranchHelper(rs < 0); | 3848 BranchHelper(rs < 0); |
(...skipping 13 matching lines...) Expand all Loading... |
3856 break; // case REGIMM. | 3862 break; // case REGIMM. |
3857 // ------------- Branch instructions. | 3863 // ------------- Branch instructions. |
3858 // When comparing to zero, the encoding of rt field is always 0, so we don't | 3864 // When comparing to zero, the encoding of rt field is always 0, so we don't |
3859 // need to replace rt with zero. | 3865 // need to replace rt with zero. |
3860 case BEQ: | 3866 case BEQ: |
3861 BranchHelper(rs == rt); | 3867 BranchHelper(rs == rt); |
3862 break; | 3868 break; |
3863 case BNE: | 3869 case BNE: |
3864 BranchHelper(rs != rt); | 3870 BranchHelper(rs != rt); |
3865 break; | 3871 break; |
3866 case BLEZ: | 3872 case POP06: // BLEZALC, BGEZALC, BGEUC, BLEZ (pre-r6) |
3867 BranchHelper(rs <= 0); | 3873 if (IsMipsArchVariant(kMips32r6)) { |
| 3874 if (rt_reg != 0) { |
| 3875 if (rs_reg == 0) { // BLEZALC |
| 3876 BranchAndLinkCompactHelper(rt <= 0, 16); |
| 3877 } else { |
| 3878 if (rs_reg == rt_reg) { // BGEZALC |
| 3879 BranchAndLinkCompactHelper(rt >= 0, 16); |
| 3880 } else { // BGEUC |
| 3881 BranchCompactHelper( |
| 3882 static_cast<uint32_t>(rs) >= static_cast<uint32_t>(rt), 16); |
| 3883 } |
| 3884 } |
| 3885 } else { // BLEZ |
| 3886 BranchHelper(rs <= 0); |
| 3887 } |
| 3888 } else { // BLEZ |
| 3889 BranchHelper(rs <= 0); |
| 3890 } |
3868 break; | 3891 break; |
3869 case BGTZ: | 3892 case POP07: // BGTZALC, BLTZALC, BLTUC, BGTZ (pre-r6) |
3870 BranchHelper(rs > 0); | 3893 if (IsMipsArchVariant(kMips32r6)) { |
| 3894 if (rt_reg != 0) { |
| 3895 if (rs_reg == 0) { // BGTZALC |
| 3896 BranchAndLinkCompactHelper(rt > 0, 16); |
| 3897 } else { |
| 3898 if (rt_reg == rs_reg) { // BLTZALC |
| 3899 BranchAndLinkCompactHelper(rt < 0, 16); |
| 3900 } else { // BLTUC |
| 3901 BranchCompactHelper( |
| 3902 static_cast<uint32_t>(rs) < static_cast<uint32_t>(rt), 16); |
| 3903 } |
| 3904 } |
| 3905 } else { // BGTZ |
| 3906 BranchHelper(rs > 0); |
| 3907 } |
| 3908 } else { // BGTZ |
| 3909 BranchHelper(rs > 0); |
| 3910 } |
3871 break; | 3911 break; |
3872 case POP66: { | 3912 case POP26: // BLEZC, BGEZC, BGEC/BLEC / BLEZL (pre-r6) |
3873 if (rs_reg) { // BEQZC | 3913 if (IsMipsArchVariant(kMips32r6)) { |
3874 int32_t se_imm21 = | 3914 if (rt_reg != 0) { |
3875 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits)); | 3915 if (rs_reg == 0) { // BLEZC |
3876 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits); | 3916 BranchCompactHelper(rt <= 0, 16); |
3877 if (rs == 0) | 3917 } else { |
3878 next_pc = current_pc + 4 + (se_imm21 << 2); | 3918 if (rs_reg == rt_reg) { // BGEZC |
3879 else | 3919 BranchCompactHelper(rt >= 0, 16); |
3880 next_pc = current_pc + 4; | 3920 } else { // BGEC/BLEC |
| 3921 BranchCompactHelper(rs >= rt, 16); |
| 3922 } |
| 3923 } |
| 3924 } |
| 3925 } else { // BLEZL |
| 3926 BranchAndLinkHelper(rs <= 0); |
| 3927 } |
| 3928 break; |
| 3929 case POP27: // BGTZC, BLTZC, BLTC/BGTC / BGTZL (pre-r6) |
| 3930 if (IsMipsArchVariant(kMips32r6)) { |
| 3931 if (rt_reg != 0) { |
| 3932 if (rs_reg == 0) { // BGTZC |
| 3933 BranchCompactHelper(rt > 0, 16); |
| 3934 } else { |
| 3935 if (rs_reg == rt_reg) { // BLTZC |
| 3936 BranchCompactHelper(rt < 0, 16); |
| 3937 } else { // BLTC/BGTC |
| 3938 BranchCompactHelper(rs < rt, 16); |
| 3939 } |
| 3940 } |
| 3941 } |
| 3942 } else { // BGTZL |
| 3943 BranchAndLinkHelper(rs > 0); |
| 3944 } |
| 3945 break; |
| 3946 case POP66: // BEQZC, JIC |
| 3947 if (rs_reg != 0) { // BEQZC |
| 3948 BranchCompactHelper(rs == 0, 21); |
3881 } else { // JIC | 3949 } else { // JIC |
| 3950 CheckForbiddenSlot(get_pc()); |
3882 next_pc = rt + imm16; | 3951 next_pc = rt + imm16; |
3883 } | 3952 } |
3884 break; | 3953 break; |
3885 } | 3954 case POP76: // BNEZC, JIALC |
3886 case BC: { | 3955 if (rs_reg != 0) { // BNEZC |
3887 next_pc = current_pc + 4 + (se_imm26 << 2); | 3956 BranchCompactHelper(rs != 0, 21); |
3888 set_pc(next_pc); | 3957 } else { // JIALC |
3889 pc_modified_ = true; | 3958 int32_t current_pc = get_pc(); |
| 3959 CheckForbiddenSlot(current_pc); |
| 3960 set_register(31, current_pc + Instruction::kInstrSize); |
| 3961 next_pc = rt + imm16; |
| 3962 } |
3890 break; | 3963 break; |
3891 } | 3964 case BC: |
3892 case BALC: { | 3965 BranchCompactHelper(true, 26); |
3893 set_register(31, current_pc + 4); | |
3894 next_pc = current_pc + 4 + (se_imm26 << 2); | |
3895 set_pc(next_pc); | |
3896 pc_modified_ = true; | |
3897 break; | 3966 break; |
3898 } | 3967 case BALC: |
3899 // ------------- Arithmetic instructions. | 3968 BranchAndLinkCompactHelper(true, 26); |
3900 case ADDI: | 3969 break; |
3901 if (HaveSameSign(rs, se_imm16)) { | 3970 case POP10: // BOVC, BEQZALC, BEQC / ADDI (pre-r6) |
3902 if (rs > 0) { | 3971 if (IsMipsArchVariant(kMips32r6)) { |
3903 if (rs <= (Registers::kMaxValue - se_imm16)) { | 3972 if (rs_reg >= rt_reg) { // BOVC |
3904 SignalException(kIntegerOverflow); | 3973 if (HaveSameSign(rs, rt)) { |
| 3974 if (rs > 0) { |
| 3975 BranchCompactHelper(rs > Registers::kMaxValue - rt, 16); |
| 3976 } else if (rs < 0) { |
| 3977 BranchCompactHelper(rs < Registers::kMinValue - rt, 16); |
| 3978 } |
3905 } | 3979 } |
3906 } else if (rs < 0) { | 3980 } else { |
3907 if (rs >= (Registers::kMinValue - se_imm16)) { | 3981 if (rs_reg == 0) { // BEQZALC |
3908 SignalException(kIntegerUnderflow); | 3982 BranchAndLinkCompactHelper(rt == 0, 16); |
| 3983 } else { // BEQC |
| 3984 BranchCompactHelper(rt == rs, 16); |
| 3985 } |
| 3986 } |
| 3987 } else { // ADDI |
| 3988 if (HaveSameSign(rs, se_imm16)) { |
| 3989 if (rs > 0) { |
| 3990 if (rs <= Registers::kMaxValue - se_imm16) { |
| 3991 SignalException(kIntegerOverflow); |
| 3992 } |
| 3993 } else if (rs < 0) { |
| 3994 if (rs >= Registers::kMinValue - se_imm16) { |
| 3995 SignalException(kIntegerUnderflow); |
| 3996 } |
| 3997 } |
| 3998 } |
| 3999 SetResult(rt_reg, rs + se_imm16); |
| 4000 } |
| 4001 break; |
| 4002 case POP30: // BNVC, BNEZALC, BNEC / DADDI (pre-r6) |
| 4003 if (IsMipsArchVariant(kMips32r6)) { |
| 4004 if (rs_reg >= rt_reg) { // BNVC |
| 4005 if (!HaveSameSign(rs, rt) || rs == 0 || rt == 0) { |
| 4006 BranchCompactHelper(true, 16); |
| 4007 } else { |
| 4008 if (rs > 0) { |
| 4009 BranchCompactHelper(rs <= Registers::kMaxValue - rt, 16); |
| 4010 } else if (rs < 0) { |
| 4011 BranchCompactHelper(rs >= Registers::kMinValue - rt, 16); |
| 4012 } |
| 4013 } |
| 4014 } else { |
| 4015 if (rs_reg == 0) { // BNEZALC |
| 4016 BranchAndLinkCompactHelper(rt != 0, 16); |
| 4017 } else { // BNEC |
| 4018 BranchCompactHelper(rt != rs, 16); |
3909 } | 4019 } |
3910 } | 4020 } |
3911 } | 4021 } |
3912 SetResult(rt_reg, rs + se_imm16); | |
3913 break; | 4022 break; |
| 4023 // ------------- Arithmetic instructions. |
3914 case ADDIU: | 4024 case ADDIU: |
3915 SetResult(rt_reg, rs + se_imm16); | 4025 SetResult(rt_reg, rs + se_imm16); |
3916 break; | 4026 break; |
3917 case SLTI: | 4027 case SLTI: |
3918 SetResult(rt_reg, rs < se_imm16 ? 1 : 0); | 4028 SetResult(rt_reg, rs < se_imm16 ? 1 : 0); |
3919 break; | 4029 break; |
3920 case SLTIU: | 4030 case SLTIU: |
3921 SetResult(rt_reg, rs_u < static_cast<uint32_t>(se_imm16) ? 1 : 0); | 4031 SetResult(rt_reg, rs_u < static_cast<uint32_t>(se_imm16) ? 1 : 0); |
3922 break; | 4032 break; |
3923 case ANDI: | 4033 case ANDI: |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4007 break; | 4117 break; |
4008 case LDC1: | 4118 case LDC1: |
4009 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); | 4119 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); |
4010 break; | 4120 break; |
4011 case SWC1: | 4121 case SWC1: |
4012 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr); | 4122 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr); |
4013 break; | 4123 break; |
4014 case SDC1: | 4124 case SDC1: |
4015 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); | 4125 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); |
4016 break; | 4126 break; |
4017 // ------------- JIALC and BNEZC instructions. | |
4018 case POP76: { | |
4019 // Next pc. | |
4020 next_pc = rt + se_imm16; | |
4021 // The instruction after the jump is NOT executed. | |
4022 int16_t pc_increment = Instruction::kInstrSize; | |
4023 if (instr->IsLinkingInstruction()) { | |
4024 set_register(31, current_pc + pc_increment); | |
4025 } | |
4026 set_pc(next_pc); | |
4027 pc_modified_ = true; | |
4028 break; | |
4029 } | |
4030 // ------------- PC-Relative instructions. | 4127 // ------------- PC-Relative instructions. |
4031 case PCREL: { | 4128 case PCREL: { |
4032 // rt field: checking 5-bits. | 4129 // rt field: checking 5-bits. |
| 4130 int32_t imm21 = instr->Imm21Value(); |
| 4131 int32_t current_pc = get_pc(); |
4033 uint8_t rt = (imm21 >> kImm16Bits); | 4132 uint8_t rt = (imm21 >> kImm16Bits); |
4034 switch (rt) { | 4133 switch (rt) { |
4035 case ALUIPC: | 4134 case ALUIPC: |
4036 addr = current_pc + (se_imm16 << 16); | 4135 addr = current_pc + (se_imm16 << 16); |
4037 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; | 4136 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; |
4038 break; | 4137 break; |
4039 case AUIPC: | 4138 case AUIPC: |
4040 alu_out = current_pc + (se_imm16 << 16); | 4139 alu_out = current_pc + (se_imm16 << 16); |
4041 break; | 4140 break; |
4042 default: { | 4141 default: { |
(...skipping 26 matching lines...) Expand all Loading... |
4069 } | 4168 } |
4070 default: | 4169 default: |
4071 UNREACHABLE(); | 4170 UNREACHABLE(); |
4072 } | 4171 } |
4073 | 4172 |
4074 if (execute_branch_delay_instruction) { | 4173 if (execute_branch_delay_instruction) { |
4075 // Execute branch delay slot | 4174 // Execute branch delay slot |
4076 // We don't check for end_sim_pc. First it should not be met as the current | 4175 // We don't check for end_sim_pc. First it should not be met as the current |
4077 // pc is valid. Secondly a jump should always execute its branch delay slot. | 4176 // pc is valid. Secondly a jump should always execute its branch delay slot. |
4078 Instruction* branch_delay_instr = | 4177 Instruction* branch_delay_instr = |
4079 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); | 4178 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); |
4080 BranchDelayInstructionDecode(branch_delay_instr); | 4179 BranchDelayInstructionDecode(branch_delay_instr); |
4081 } | 4180 } |
4082 | 4181 |
4083 // If needed update pc after the branch delay execution. | 4182 // If needed update pc after the branch delay execution. |
4084 if (next_pc != bad_ra) { | 4183 if (next_pc != bad_ra) { |
4085 set_pc(next_pc); | 4184 set_pc(next_pc); |
4086 } | 4185 } |
4087 } | 4186 } |
4088 | 4187 |
4089 #undef BranchHelper | |
4090 #undef BranchAndLinkHelper | |
4091 | |
4092 | 4188 |
4093 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). | 4189 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). |
4094 void Simulator::DecodeTypeJump(Instruction* instr) { | 4190 void Simulator::DecodeTypeJump(Instruction* instr) { |
4095 // Get current pc. | 4191 // Get current pc. |
4096 int32_t current_pc = get_pc(); | 4192 int32_t current_pc = get_pc(); |
4097 // Get unchanged bits of pc. | 4193 // Get unchanged bits of pc. |
4098 int32_t pc_high_bits = current_pc & 0xf0000000; | 4194 int32_t pc_high_bits = current_pc & 0xf0000000; |
4099 // Next pc. | 4195 // Next pc. |
4100 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); | 4196 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); |
4101 | 4197 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4167 icount_++; | 4263 icount_++; |
4168 InstructionDecode(instr); | 4264 InstructionDecode(instr); |
4169 program_counter = get_pc(); | 4265 program_counter = get_pc(); |
4170 } | 4266 } |
4171 } else { | 4267 } else { |
4172 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when | 4268 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when |
4173 // we reach the particular instuction count. | 4269 // we reach the particular instuction count. |
4174 while (program_counter != end_sim_pc) { | 4270 while (program_counter != end_sim_pc) { |
4175 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); | 4271 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); |
4176 icount_++; | 4272 icount_++; |
4177 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { | 4273 if (icount_ == static_cast<uint64_t>(::v8::internal::FLAG_stop_sim_at)) { |
4178 MipsDebugger dbg(this); | 4274 MipsDebugger dbg(this); |
4179 dbg.Debug(); | 4275 dbg.Debug(); |
4180 } else { | 4276 } else { |
4181 InstructionDecode(instr); | 4277 InstructionDecode(instr); |
4182 } | 4278 } |
4183 program_counter = get_pc(); | 4279 program_counter = get_pc(); |
4184 } | 4280 } |
4185 } | 4281 } |
4186 } | 4282 } |
4187 | 4283 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4335 | 4431 |
4336 | 4432 |
4337 #undef UNSUPPORTED | 4433 #undef UNSUPPORTED |
4338 | 4434 |
4339 } // namespace internal | 4435 } // namespace internal |
4340 } // namespace v8 | 4436 } // namespace v8 |
4341 | 4437 |
4342 #endif // USE_SIMULATOR | 4438 #endif // USE_SIMULATOR |
4343 | 4439 |
4344 #endif // V8_TARGET_ARCH_MIPS | 4440 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |