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. |
paul.l...
2015/10/15 01:51:24
lambda functions! Cool.... reads nicely from the c
| |
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: |
paul.l...
2015/10/15 01:51:24
even though the actual instruction names are just
balazs.kilvady
2015/10/30 21:11:14
Done.
| |
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: |
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 } | |
3911 break; | |
3912 case POP26: | |
3913 if (IsMipsArchVariant(kMips32r6)) { | |
3914 if (rt_reg != 0) { | |
3915 if (rs_reg == 0) { // BLEZC | |
3916 BranchCompactHelper(rt <= 0, 16); | |
3917 } else { | |
3918 if (rs_reg == rt_reg) { // BGEZC | |
3919 BranchCompactHelper(rt >= 0, 16); | |
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: | |
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 } | |
3871 break; | 3945 break; |
3872 case POP66: { | 3946 case POP66: { |
3873 if (rs_reg) { // BEQZC | 3947 if (rs_reg != 0) { // BEQZC |
3874 int32_t se_imm21 = | 3948 BranchCompactHelper(rs == 0, 21); |
3875 static_cast<int32_t>(imm21 << (kOpcodeBits + kRsBits)); | |
3876 se_imm21 = se_imm21 >> (kOpcodeBits + kRsBits); | |
3877 if (rs == 0) | |
3878 next_pc = current_pc + 4 + (se_imm21 << 2); | |
3879 else | |
3880 next_pc = current_pc + 4; | |
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 } |
3886 case BC: { | 3955 case POP76: { |
3887 next_pc = current_pc + 4 + (se_imm26 << 2); | 3956 if (rs_reg != 0) { // BNEZC |
3888 set_pc(next_pc); | 3957 BranchCompactHelper(rs != 0, 21); |
3889 pc_modified_ = true; | 3958 } else { // JIALC |
3959 int32_t current_pc = get_pc(); | |
3960 CheckForbiddenSlot(current_pc); | |
3961 set_register(31, current_pc + Instruction::kInstrSize); | |
3962 next_pc = rt + imm16; | |
3963 } | |
3890 break; | 3964 break; |
3891 } | 3965 } |
3892 case BALC: { | 3966 case BC: |
3893 set_register(31, current_pc + 4); | 3967 BranchCompactHelper(true, 26); |
3894 next_pc = current_pc + 4 + (se_imm26 << 2); | |
3895 set_pc(next_pc); | |
3896 pc_modified_ = true; | |
3897 break; | 3968 break; |
3898 } | 3969 case BALC: |
3899 // ------------- Arithmetic instructions. | 3970 BranchAndLinkCompactHelper(true, 26); |
3900 case ADDI: | 3971 break; |
3901 if (HaveSameSign(rs, se_imm16)) { | 3972 case POP10: |
3902 if (rs > 0) { | 3973 if (IsMipsArchVariant(kMips32r6)) { |
3903 if (rs <= (Registers::kMaxValue - se_imm16)) { | 3974 // R6 check if BOVC, BEQZALC or BEQC instruction. |
3904 SignalException(kIntegerOverflow); | 3975 if (rs_reg >= rt_reg) { // BOVC |
3976 if (HaveSameSign(rs, rt)) { | |
3977 if (rs > 0) { | |
3978 BranchCompactHelper(rs > Registers::kMaxValue - rt, 16); | |
3979 } else if (rs < 0) { | |
3980 BranchCompactHelper(rs < Registers::kMinValue - rt, 16); | |
3981 } | |
3905 } | 3982 } |
3906 } else if (rs < 0) { | 3983 } else { |
3907 if (rs >= (Registers::kMinValue - se_imm16)) { | 3984 if (rs_reg == 0) { // BEQZALC |
3908 SignalException(kIntegerUnderflow); | 3985 BranchAndLinkCompactHelper(rt == 0, 16); |
3986 } else { // BEQC | |
3987 BranchCompactHelper(rt == rs, 16); | |
3988 } | |
3989 } | |
3990 } else { // ADDI | |
3991 if (HaveSameSign(rs, se_imm16)) { | |
3992 if (rs > 0) { | |
3993 if (rs <= Registers::kMaxValue - se_imm16) { | |
3994 SignalException(kIntegerOverflow); | |
3995 } | |
3996 } else if (rs < 0) { | |
3997 if (rs >= Registers::kMinValue - se_imm16) { | |
3998 SignalException(kIntegerUnderflow); | |
3999 } | |
4000 } | |
4001 } | |
4002 SetResult(rt_reg, rs + se_imm16); | |
4003 } | |
4004 break; | |
4005 case POP30: | |
4006 if (IsMipsArchVariant(kMips32r6)) { | |
4007 // R6 check if BNVC, BNEZALC or BNEC instruction. | |
4008 if (rs_reg >= rt_reg) { // BNVC | |
4009 if (!HaveSameSign(rs, rt) || rs == 0 || rt == 0) { | |
4010 BranchCompactHelper(true, 16); | |
4011 } else { | |
4012 if (rs > 0) { | |
4013 BranchCompactHelper(rs <= Registers::kMaxValue - rt, 16); | |
4014 } else if (rs < 0) { | |
4015 BranchCompactHelper(rs >= Registers::kMinValue - rt, 16); | |
4016 } | |
4017 } | |
4018 } else { | |
4019 if (rs_reg == 0) { // BNEZALC | |
4020 BranchAndLinkCompactHelper(rt != 0, 16); | |
4021 } else { // BNEC | |
4022 BranchCompactHelper(rt != rs, 16); | |
3909 } | 4023 } |
3910 } | 4024 } |
3911 } | 4025 } |
3912 SetResult(rt_reg, rs + se_imm16); | |
3913 break; | 4026 break; |
4027 // ------------- Arithmetic instructions. | |
3914 case ADDIU: | 4028 case ADDIU: |
3915 SetResult(rt_reg, rs + se_imm16); | 4029 SetResult(rt_reg, rs + se_imm16); |
3916 break; | 4030 break; |
3917 case SLTI: | 4031 case SLTI: |
3918 SetResult(rt_reg, rs < se_imm16 ? 1 : 0); | 4032 SetResult(rt_reg, rs < se_imm16 ? 1 : 0); |
3919 break; | 4033 break; |
3920 case SLTIU: | 4034 case SLTIU: |
3921 SetResult(rt_reg, rs_u < static_cast<uint32_t>(se_imm16) ? 1 : 0); | 4035 SetResult(rt_reg, rs_u < static_cast<uint32_t>(se_imm16) ? 1 : 0); |
3922 break; | 4036 break; |
3923 case ANDI: | 4037 case ANDI: |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4007 break; | 4121 break; |
4008 case LDC1: | 4122 case LDC1: |
4009 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); | 4123 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); |
4010 break; | 4124 break; |
4011 case SWC1: | 4125 case SWC1: |
4012 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr); | 4126 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr); |
4013 break; | 4127 break; |
4014 case SDC1: | 4128 case SDC1: |
4015 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); | 4129 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); |
4016 break; | 4130 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. | 4131 // ------------- PC-Relative instructions. |
4031 case PCREL: { | 4132 case PCREL: { |
4032 // rt field: checking 5-bits. | 4133 // rt field: checking 5-bits. |
4134 int32_t imm21 = instr->Imm21Value(); | |
4135 int32_t current_pc = get_pc(); | |
4033 uint8_t rt = (imm21 >> kImm16Bits); | 4136 uint8_t rt = (imm21 >> kImm16Bits); |
4034 switch (rt) { | 4137 switch (rt) { |
4035 case ALUIPC: | 4138 case ALUIPC: |
4036 addr = current_pc + (se_imm16 << 16); | 4139 addr = current_pc + (se_imm16 << 16); |
4037 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; | 4140 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; |
4038 break; | 4141 break; |
4039 case AUIPC: | 4142 case AUIPC: |
4040 alu_out = current_pc + (se_imm16 << 16); | 4143 alu_out = current_pc + (se_imm16 << 16); |
4041 break; | 4144 break; |
4042 default: { | 4145 default: { |
(...skipping 26 matching lines...) Expand all Loading... | |
4069 } | 4172 } |
4070 default: | 4173 default: |
4071 UNREACHABLE(); | 4174 UNREACHABLE(); |
4072 } | 4175 } |
4073 | 4176 |
4074 if (execute_branch_delay_instruction) { | 4177 if (execute_branch_delay_instruction) { |
4075 // Execute branch delay slot | 4178 // Execute branch delay slot |
4076 // We don't check for end_sim_pc. First it should not be met as the current | 4179 // 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. | 4180 // pc is valid. Secondly a jump should always execute its branch delay slot. |
4078 Instruction* branch_delay_instr = | 4181 Instruction* branch_delay_instr = |
4079 reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize); | 4182 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); |
4080 BranchDelayInstructionDecode(branch_delay_instr); | 4183 BranchDelayInstructionDecode(branch_delay_instr); |
4081 } | 4184 } |
4082 | 4185 |
4083 // If needed update pc after the branch delay execution. | 4186 // If needed update pc after the branch delay execution. |
4084 if (next_pc != bad_ra) { | 4187 if (next_pc != bad_ra) { |
4085 set_pc(next_pc); | 4188 set_pc(next_pc); |
4086 } | 4189 } |
4087 } | 4190 } |
4088 | 4191 |
4089 #undef BranchHelper | |
4090 #undef BranchAndLinkHelper | |
4091 | |
4092 | 4192 |
4093 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). | 4193 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). |
4094 void Simulator::DecodeTypeJump(Instruction* instr) { | 4194 void Simulator::DecodeTypeJump(Instruction* instr) { |
4095 // Get current pc. | 4195 // Get current pc. |
4096 int32_t current_pc = get_pc(); | 4196 int32_t current_pc = get_pc(); |
4097 // Get unchanged bits of pc. | 4197 // Get unchanged bits of pc. |
4098 int32_t pc_high_bits = current_pc & 0xf0000000; | 4198 int32_t pc_high_bits = current_pc & 0xf0000000; |
4099 // Next pc. | 4199 // Next pc. |
4100 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); | 4200 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); |
4101 | 4201 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4167 icount_++; | 4267 icount_++; |
4168 InstructionDecode(instr); | 4268 InstructionDecode(instr); |
4169 program_counter = get_pc(); | 4269 program_counter = get_pc(); |
4170 } | 4270 } |
4171 } else { | 4271 } else { |
4172 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when | 4272 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when |
4173 // we reach the particular instuction count. | 4273 // we reach the particular instuction count. |
4174 while (program_counter != end_sim_pc) { | 4274 while (program_counter != end_sim_pc) { |
4175 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); | 4275 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); |
4176 icount_++; | 4276 icount_++; |
4177 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { | 4277 if (icount_ == static_cast<uint64_t>(::v8::internal::FLAG_stop_sim_at)) { |
4178 MipsDebugger dbg(this); | 4278 MipsDebugger dbg(this); |
4179 dbg.Debug(); | 4279 dbg.Debug(); |
4180 } else { | 4280 } else { |
4181 InstructionDecode(instr); | 4281 InstructionDecode(instr); |
4182 } | 4282 } |
4183 program_counter = get_pc(); | 4283 program_counter = get_pc(); |
4184 } | 4284 } |
4185 } | 4285 } |
4186 } | 4286 } |
4187 | 4287 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4335 | 4435 |
4336 | 4436 |
4337 #undef UNSUPPORTED | 4437 #undef UNSUPPORTED |
4338 | 4438 |
4339 } // namespace internal | 4439 } // namespace internal |
4340 } // namespace v8 | 4440 } // namespace v8 |
4341 | 4441 |
4342 #endif // USE_SIMULATOR | 4442 #endif // USE_SIMULATOR |
4343 | 4443 |
4344 #endif // V8_TARGET_ARCH_MIPS | 4444 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |