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

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

Issue 2375673002: MIPS64: Improve performance of simulator in debug mode. (Closed)
Patch Set: Created 4 years, 2 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
« src/mips64/constants-mips64.h ('K') | « src/mips64/simulator-mips64.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 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_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // Set or delete a breakpoint. Returns true if successful. 89 // Set or delete a breakpoint. Returns true if successful.
90 bool SetBreakpoint(Instruction* breakpc); 90 bool SetBreakpoint(Instruction* breakpc);
91 bool DeleteBreakpoint(Instruction* breakpc); 91 bool DeleteBreakpoint(Instruction* breakpc);
92 92
93 // Undo and redo all breakpoints. This is needed to bracket disassembly and 93 // Undo and redo all breakpoints. This is needed to bracket disassembly and
94 // execution to skip past breakpoints when run from the debugger. 94 // execution to skip past breakpoints when run from the debugger.
95 void UndoBreakpoints(); 95 void UndoBreakpoints();
96 void RedoBreakpoints(); 96 void RedoBreakpoints();
97 }; 97 };
98 98
99 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n"); 99 inline void UNSUPPORTED() { printf("Sim: Unsupported instruction.\n"); }
100 100
101 void MipsDebugger::Stop(Instruction* instr) { 101 void MipsDebugger::Stop(Instruction* instr) {
102 // Get the stop code. 102 // Get the stop code.
103 uint32_t code = instr->Bits(25, 6); 103 uint32_t code = instr->Bits(25, 6);
104 PrintF("Simulator hit (%u)\n", code); 104 PrintF("Simulator hit (%u)\n", code);
105 // TODO(yuyin): 2 -> 3? 105 // TODO(yuyin): 2 -> 3?
106 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstrSize); 106 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstrSize);
107 Debug(); 107 Debug();
108 } 108 }
109 109
(...skipping 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0); 1928 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
1929 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1); 1929 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);
1930 1930
1931 // This signature supports direct call to accessor getter callback. 1931 // This signature supports direct call to accessor getter callback.
1932 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1); 1932 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
1933 typedef void (*SimulatorRuntimeProfilingGetterCall)( 1933 typedef void (*SimulatorRuntimeProfilingGetterCall)(
1934 int64_t arg0, int64_t arg1, void* arg2); 1934 int64_t arg0, int64_t arg1, void* arg2);
1935 1935
1936 // Software interrupt instructions are used by the simulator to call into the 1936 // Software interrupt instructions are used by the simulator to call into the
1937 // C-based V8 runtime. They are also used for debugging with simulator. 1937 // C-based V8 runtime. They are also used for debugging with simulator.
1938 void Simulator::SoftwareInterrupt(Instruction* instr) { 1938 void Simulator::SoftwareInterrupt() {
1939 // There are several instructions that could get us here, 1939 // There are several instructions that could get us here,
1940 // the break_ instruction, or several variants of traps. All 1940 // the break_ instruction, or several variants of traps. All
1941 // Are "SPECIAL" class opcode, and are distinuished by function. 1941 // Are "SPECIAL" class opcode, and are distinuished by function.
1942 int32_t func = instr->FunctionFieldRaw(); 1942 int32_t func = instr_.FunctionFieldRaw();
1943 uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1; 1943 uint32_t code = (func == BREAK) ? instr_.Bits(25, 6) : -1;
1944 // We first check if we met a call_rt_redirected. 1944 // We first check if we met a call_rt_redirected.
1945 if (instr->InstructionBits() == rtCallRedirInstr) { 1945 if (instr_.InstructionBits() == rtCallRedirInstr) {
1946 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1946 Redirection* redirection = Redirection::FromSwiInstruction(instr_.instr());
1947 int64_t arg0 = get_register(a0); 1947 int64_t arg0 = get_register(a0);
1948 int64_t arg1 = get_register(a1); 1948 int64_t arg1 = get_register(a1);
1949 int64_t arg2 = get_register(a2); 1949 int64_t arg2 = get_register(a2);
1950 int64_t arg3 = get_register(a3); 1950 int64_t arg3 = get_register(a3);
1951 int64_t arg4, arg5; 1951 int64_t arg4, arg5;
1952 1952
1953 arg4 = get_register(a4); // Abi n64 register a4. 1953 arg4 = get_register(a4); // Abi n64 register a4.
1954 arg5 = get_register(a5); // Abi n64 register a5. 1954 arg5 = get_register(a5); // Abi n64 register a5.
1955 1955
1956 bool fp_call = 1956 bool fp_call =
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 get_register(v0)); 2162 get_register(v0));
2163 } 2163 }
2164 set_register(ra, saved_ra); 2164 set_register(ra, saved_ra);
2165 set_pc(get_register(ra)); 2165 set_pc(get_register(ra));
2166 2166
2167 } else if (func == BREAK && code <= kMaxStopCode) { 2167 } else if (func == BREAK && code <= kMaxStopCode) {
2168 if (IsWatchpoint(code)) { 2168 if (IsWatchpoint(code)) {
2169 PrintWatchpoint(code); 2169 PrintWatchpoint(code);
2170 } else { 2170 } else {
2171 IncreaseStopCounter(code); 2171 IncreaseStopCounter(code);
2172 HandleStop(code, instr); 2172 HandleStop(code, instr_.instr());
2173 } 2173 }
2174 } else { 2174 } else {
2175 // All remaining break_ codes, and all traps are handled here. 2175 // All remaining break_ codes, and all traps are handled here.
2176 MipsDebugger dbg(this); 2176 MipsDebugger dbg(this);
2177 dbg.Debug(); 2177 dbg.Debug();
2178 } 2178 }
2179 } 2179 }
2180 2180
2181 2181
2182 // Stop helper functions. 2182 // Stop helper functions.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 // Handle execution based on instruction types. 2410 // Handle execution based on instruction types.
2411 2411
2412 void Simulator::DecodeTypeRegisterSRsType() { 2412 void Simulator::DecodeTypeRegisterSRsType() {
2413 float fs, ft, fd; 2413 float fs, ft, fd;
2414 fs = get_fpu_register_float(fs_reg()); 2414 fs = get_fpu_register_float(fs_reg());
2415 ft = get_fpu_register_float(ft_reg()); 2415 ft = get_fpu_register_float(ft_reg());
2416 fd = get_fpu_register_float(fd_reg()); 2416 fd = get_fpu_register_float(fd_reg());
2417 int32_t ft_int = bit_cast<int32_t>(ft); 2417 int32_t ft_int = bit_cast<int32_t>(ft);
2418 int32_t fd_int = bit_cast<int32_t>(fd); 2418 int32_t fd_int = bit_cast<int32_t>(fd);
2419 uint32_t cc, fcsr_cc; 2419 uint32_t cc, fcsr_cc;
2420 cc = get_instr()->FCccValue(); 2420 cc = instr_.FCccValue();
2421 fcsr_cc = get_fcsr_condition_bit(cc); 2421 fcsr_cc = get_fcsr_condition_bit(cc);
2422 switch (get_instr()->FunctionFieldRaw()) { 2422 switch (instr_.FunctionFieldRaw()) {
2423 case RINT: { 2423 case RINT: {
2424 DCHECK(kArchVariant == kMips64r6); 2424 DCHECK(kArchVariant == kMips64r6);
2425 float result, temp_result; 2425 float result, temp_result;
2426 double temp; 2426 double temp;
2427 float upper = std::ceil(fs); 2427 float upper = std::ceil(fs);
2428 float lower = std::floor(fs); 2428 float lower = std::floor(fs);
2429 switch (get_fcsr_rounding_mode()) { 2429 switch (get_fcsr_rounding_mode()) {
2430 case kRoundToNearest: 2430 case kRoundToNearest:
2431 if (upper - fs < fs - lower) { 2431 if (upper - fs < fs - lower) {
2432 result = upper; 2432 result = upper;
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
2756 if (rt() != 0) { 2756 if (rt() != 0) {
2757 set_fpu_register_float(fd_reg(), fs); 2757 set_fpu_register_float(fd_reg(), fs);
2758 } 2758 }
2759 break; 2759 break;
2760 } 2760 }
2761 case MOVF: { 2761 case MOVF: {
2762 // Same function field for MOVT.D and MOVF.D 2762 // Same function field for MOVT.D and MOVF.D
2763 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 2763 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
2764 ft_cc = get_fcsr_condition_bit(ft_cc); 2764 ft_cc = get_fcsr_condition_bit(ft_cc);
2765 2765
2766 if (get_instr()->Bit(16)) { // Read Tf bit. 2766 if (instr_.Bit(16)) { // Read Tf bit.
2767 // MOVT.D 2767 // MOVT.D
2768 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 2768 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
2769 } else { 2769 } else {
2770 // MOVF.D 2770 // MOVF.D
2771 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 2771 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
2772 } 2772 }
2773 break; 2773 break;
2774 } 2774 }
2775 default: 2775 default:
2776 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S 2776 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
2777 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. 2777 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
2778 UNREACHABLE(); 2778 UNREACHABLE();
2779 } 2779 }
2780 } 2780 }
2781 2781
2782 2782
2783 void Simulator::DecodeTypeRegisterDRsType() { 2783 void Simulator::DecodeTypeRegisterDRsType() {
2784 double ft, fs, fd; 2784 double ft, fs, fd;
2785 uint32_t cc, fcsr_cc; 2785 uint32_t cc, fcsr_cc;
2786 fs = get_fpu_register_double(fs_reg()); 2786 fs = get_fpu_register_double(fs_reg());
2787 ft = (get_instr()->FunctionFieldRaw() != MOVF) 2787 ft = (instr_.FunctionFieldRaw() != MOVF) ? get_fpu_register_double(ft_reg())
2788 ? get_fpu_register_double(ft_reg()) 2788 : 0.0;
2789 : 0.0;
2790 fd = get_fpu_register_double(fd_reg()); 2789 fd = get_fpu_register_double(fd_reg());
2791 cc = get_instr()->FCccValue(); 2790 cc = instr_.FCccValue();
2792 fcsr_cc = get_fcsr_condition_bit(cc); 2791 fcsr_cc = get_fcsr_condition_bit(cc);
2793 int64_t ft_int = bit_cast<int64_t>(ft); 2792 int64_t ft_int = bit_cast<int64_t>(ft);
2794 int64_t fd_int = bit_cast<int64_t>(fd); 2793 int64_t fd_int = bit_cast<int64_t>(fd);
2795 switch (get_instr()->FunctionFieldRaw()) { 2794 switch (instr_.FunctionFieldRaw()) {
2796 case RINT: { 2795 case RINT: {
2797 DCHECK(kArchVariant == kMips64r6); 2796 DCHECK(kArchVariant == kMips64r6);
2798 double result, temp, temp_result; 2797 double result, temp, temp_result;
2799 double upper = std::ceil(fs); 2798 double upper = std::ceil(fs);
2800 double lower = std::floor(fs); 2799 double lower = std::floor(fs);
2801 switch (get_fcsr_rounding_mode()) { 2800 switch (get_fcsr_rounding_mode()) {
2802 case kRoundToNearest: 2801 case kRoundToNearest:
2803 if (upper - fs < fs - lower) { 2802 if (upper - fs < fs - lower) {
2804 result = upper; 2803 result = upper;
2805 } else if (upper - fs > fs - lower) { 2804 } else if (upper - fs > fs - lower) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2853 DCHECK(kArchVariant == kMips64r2); 2852 DCHECK(kArchVariant == kMips64r2);
2854 if (rt() != 0) { 2853 if (rt() != 0) {
2855 set_fpu_register_double(fd_reg(), fs); 2854 set_fpu_register_double(fd_reg(), fs);
2856 } 2855 }
2857 break; 2856 break;
2858 } 2857 }
2859 case MOVF: { 2858 case MOVF: {
2860 // Same function field for MOVT.D and MOVF.D 2859 // Same function field for MOVT.D and MOVF.D
2861 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 2860 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
2862 ft_cc = get_fcsr_condition_bit(ft_cc); 2861 ft_cc = get_fcsr_condition_bit(ft_cc);
2863 if (get_instr()->Bit(16)) { // Read Tf bit. 2862 if (instr_.Bit(16)) { // Read Tf bit.
2864 // MOVT.D 2863 // MOVT.D
2865 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2864 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2866 } else { 2865 } else {
2867 // MOVF.D 2866 // MOVF.D
2868 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2867 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2869 } 2868 }
2870 break; 2869 break;
2871 } 2870 }
2872 case MINA: 2871 case MINA:
2873 DCHECK(kArchVariant == kMips64r6); 2872 DCHECK(kArchVariant == kMips64r6);
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3144 default: 3143 default:
3145 UNREACHABLE(); 3144 UNREACHABLE();
3146 } 3145 }
3147 } 3146 }
3148 3147
3149 3148
3150 void Simulator::DecodeTypeRegisterWRsType() { 3149 void Simulator::DecodeTypeRegisterWRsType() {
3151 float fs = get_fpu_register_float(fs_reg()); 3150 float fs = get_fpu_register_float(fs_reg());
3152 float ft = get_fpu_register_float(ft_reg()); 3151 float ft = get_fpu_register_float(ft_reg());
3153 int64_t alu_out = 0x12345678; 3152 int64_t alu_out = 0x12345678;
3154 switch (get_instr()->FunctionFieldRaw()) { 3153 switch (instr_.FunctionFieldRaw()) {
3155 case CVT_S_W: // Convert word to float (single). 3154 case CVT_S_W: // Convert word to float (single).
3156 alu_out = get_fpu_register_signed_word(fs_reg()); 3155 alu_out = get_fpu_register_signed_word(fs_reg());
3157 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); 3156 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out));
3158 break; 3157 break;
3159 case CVT_D_W: // Convert word to double. 3158 case CVT_D_W: // Convert word to double.
3160 alu_out = get_fpu_register_signed_word(fs_reg()); 3159 alu_out = get_fpu_register_signed_word(fs_reg());
3161 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); 3160 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out));
3162 break; 3161 break;
3163 case CMP_AF: 3162 case CMP_AF:
3164 set_fpu_register_word(fd_reg(), 0); 3163 set_fpu_register_word(fd_reg(), 0);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3236 default: 3235 default:
3237 UNREACHABLE(); 3236 UNREACHABLE();
3238 } 3237 }
3239 } 3238 }
3240 3239
3241 3240
3242 void Simulator::DecodeTypeRegisterLRsType() { 3241 void Simulator::DecodeTypeRegisterLRsType() {
3243 double fs = get_fpu_register_double(fs_reg()); 3242 double fs = get_fpu_register_double(fs_reg());
3244 double ft = get_fpu_register_double(ft_reg()); 3243 double ft = get_fpu_register_double(ft_reg());
3245 int64_t i64; 3244 int64_t i64;
3246 switch (get_instr()->FunctionFieldRaw()) { 3245 switch (instr_.FunctionFieldRaw()) {
3247 case CVT_D_L: // Mips32r2 instruction. 3246 case CVT_D_L: // Mips32r2 instruction.
3248 i64 = get_fpu_register(fs_reg()); 3247 i64 = get_fpu_register(fs_reg());
3249 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); 3248 set_fpu_register_double(fd_reg(), static_cast<double>(i64));
3250 break; 3249 break;
3251 case CVT_S_L: 3250 case CVT_S_L:
3252 i64 = get_fpu_register(fs_reg()); 3251 i64 = get_fpu_register(fs_reg());
3253 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); 3252 set_fpu_register_float(fd_reg(), static_cast<float>(i64));
3254 break; 3253 break;
3255 case CMP_AF: 3254 case CMP_AF:
3256 set_fpu_register(fd_reg(), 0); 3255 set_fpu_register(fd_reg(), 0);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 set_fpu_register(fd_reg(), 0); 3324 set_fpu_register(fd_reg(), 0);
3326 } 3325 }
3327 break; 3326 break;
3328 default: 3327 default:
3329 UNREACHABLE(); 3328 UNREACHABLE();
3330 } 3329 }
3331 } 3330 }
3332 3331
3333 3332
3334 void Simulator::DecodeTypeRegisterCOP1() { 3333 void Simulator::DecodeTypeRegisterCOP1() {
3335 switch (get_instr()->RsFieldRaw()) { 3334 switch (instr_.RsFieldRaw()) {
3336 case BC1: // Branch on coprocessor condition. 3335 case BC1: // Branch on coprocessor condition.
3337 case BC1EQZ: 3336 case BC1EQZ:
3338 case BC1NEZ: 3337 case BC1NEZ:
3339 UNREACHABLE(); 3338 UNREACHABLE();
3340 break; 3339 break;
3341 case CFC1: 3340 case CFC1:
3342 // At the moment only FCSR is supported. 3341 // At the moment only FCSR is supported.
3343 DCHECK(fs_reg() == kFCSRRegister); 3342 DCHECK(fs_reg() == kFCSRRegister);
3344 set_register(rt_reg(), FCSR_); 3343 set_register(rt_reg(), FCSR_);
3345 break; 3344 break;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3388 case L: 3387 case L:
3389 DecodeTypeRegisterLRsType(); 3388 DecodeTypeRegisterLRsType();
3390 break; 3389 break;
3391 default: 3390 default:
3392 UNREACHABLE(); 3391 UNREACHABLE();
3393 } 3392 }
3394 } 3393 }
3395 3394
3396 3395
3397 void Simulator::DecodeTypeRegisterCOP1X() { 3396 void Simulator::DecodeTypeRegisterCOP1X() {
3398 switch (get_instr()->FunctionFieldRaw()) { 3397 switch (instr_.FunctionFieldRaw()) {
3399 case MADD_S: { 3398 case MADD_S: {
3400 DCHECK(kArchVariant == kMips64r2); 3399 DCHECK(kArchVariant == kMips64r2);
3401 float fr, ft, fs; 3400 float fr, ft, fs;
3402 fr = get_fpu_register_float(fr_reg()); 3401 fr = get_fpu_register_float(fr_reg());
3403 fs = get_fpu_register_float(fs_reg()); 3402 fs = get_fpu_register_float(fs_reg());
3404 ft = get_fpu_register_float(ft_reg()); 3403 ft = get_fpu_register_float(ft_reg());
3405 set_fpu_register_float(fd_reg(), fs * ft + fr); 3404 set_fpu_register_float(fd_reg(), fs * ft + fr);
3406 break; 3405 break;
3407 } 3406 }
3408 case MSUB_S: { 3407 case MSUB_S: {
(...skipping 28 matching lines...) Expand all
3437 } 3436 }
3438 } 3437 }
3439 3438
3440 3439
3441 void Simulator::DecodeTypeRegisterSPECIAL() { 3440 void Simulator::DecodeTypeRegisterSPECIAL() {
3442 int64_t i64hilo; 3441 int64_t i64hilo;
3443 uint64_t u64hilo; 3442 uint64_t u64hilo;
3444 int64_t alu_out; 3443 int64_t alu_out;
3445 bool do_interrupt = false; 3444 bool do_interrupt = false;
3446 3445
3447 switch (get_instr()->FunctionFieldRaw()) { 3446 switch (instr_.FunctionFieldRaw()) {
3448 case SELEQZ_S: 3447 case SELEQZ_S:
3449 DCHECK(kArchVariant == kMips64r6); 3448 DCHECK(kArchVariant == kMips64r6);
3450 set_register(rd_reg(), rt() == 0 ? rs() : 0); 3449 set_register(rd_reg(), rt() == 0 ? rs() : 0);
3451 break; 3450 break;
3452 case SELNEZ_S: 3451 case SELNEZ_S:
3453 DCHECK(kArchVariant == kMips64r6); 3452 DCHECK(kArchVariant == kMips64r6);
3454 set_register(rd_reg(), rt() != 0 ? rs() : 0); 3453 set_register(rd_reg(), rt() != 0 ? rs() : 0);
3455 break; 3454 break;
3456 case JR: { 3455 case JR: {
3457 int64_t next_pc = rs(); 3456 int64_t next_pc = rs();
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3683 break; 3682 break;
3684 } 3683 }
3685 } 3684 }
3686 break; 3685 break;
3687 case DMULTU: 3686 case DMULTU:
3688 UNIMPLEMENTED_MIPS(); 3687 UNIMPLEMENTED_MIPS();
3689 break; 3688 break;
3690 case DIV: 3689 case DIV:
3691 case DDIV: { 3690 case DDIV: {
3692 const int64_t int_min_value = 3691 const int64_t int_min_value =
3693 get_instr()->FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN; 3692 instr_.FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN;
3694 switch (kArchVariant) { 3693 switch (kArchVariant) {
3695 case kMips64r2: 3694 case kMips64r2:
3696 // Divide by zero and overflow was not checked in the 3695 // Divide by zero and overflow was not checked in the
3697 // configuration step - div and divu do not raise exceptions. On 3696 // configuration step - div and divu do not raise exceptions. On
3698 // division by 0 the result will be UNPREDICTABLE. On overflow 3697 // division by 0 the result will be UNPREDICTABLE. On overflow
3699 // (INT_MIN/-1), return INT_MIN which is what the hardware does. 3698 // (INT_MIN/-1), return INT_MIN which is what the hardware does.
3700 if (rs() == int_min_value && rt() == -1) { 3699 if (rs() == int_min_value && rt() == -1) {
3701 set_register(LO, int_min_value); 3700 set_register(LO, int_min_value);
3702 set_register(HI, 0); 3701 set_register(HI, 0);
3703 } else if (rt() != 0) { 3702 } else if (rt() != 0) {
(...skipping 25 matching lines...) Expand all
3729 default: 3728 default:
3730 break; 3729 break;
3731 } 3730 }
3732 break; 3731 break;
3733 } 3732 }
3734 case DIVU: 3733 case DIVU:
3735 switch (kArchVariant) { 3734 switch (kArchVariant) {
3736 case kMips64r6: { 3735 case kMips64r6: {
3737 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); 3736 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u());
3738 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); 3737 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u());
3739 switch (get_instr()->SaValue()) { 3738 switch (sa()) {
3740 case DIV_OP: 3739 case DIV_OP:
3741 if (rt_u_32 != 0) { 3740 if (rt_u_32 != 0) {
3742 set_register(rd_reg(), rs_u_32 / rt_u_32); 3741 set_register(rd_reg(), rs_u_32 / rt_u_32);
3743 } 3742 }
3744 break; 3743 break;
3745 case MOD_OP: 3744 case MOD_OP:
3746 if (rt_u() != 0) { 3745 if (rt_u() != 0) {
3747 set_register(rd_reg(), rs_u_32 % rt_u_32); 3746 set_register(rd_reg(), rs_u_32 % rt_u_32);
3748 } 3747 }
3749 break; 3748 break;
3750 default: 3749 default:
3751 UNIMPLEMENTED_MIPS(); 3750 UNIMPLEMENTED_MIPS();
3752 break; 3751 break;
3753 } 3752 }
3754 } break; 3753 } break;
3755 default: { 3754 default: {
3756 if (rt_u() != 0) { 3755 if (rt_u() != 0) {
3757 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); 3756 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u());
3758 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); 3757 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u());
3759 set_register(LO, rs_u_32 / rt_u_32); 3758 set_register(LO, rs_u_32 / rt_u_32);
3760 set_register(HI, rs_u_32 % rt_u_32); 3759 set_register(HI, rs_u_32 % rt_u_32);
3761 } 3760 }
3762 } 3761 }
3763 } 3762 }
3764 break; 3763 break;
3765 case DDIVU: 3764 case DDIVU:
3766 switch (kArchVariant) { 3765 switch (kArchVariant) {
3767 case kMips64r6: { 3766 case kMips64r6: {
3768 switch (get_instr()->SaValue()) { 3767 switch (instr_.SaValue()) {
3769 case DIV_OP: 3768 case DIV_OP:
3770 if (rt_u() != 0) { 3769 if (rt_u() != 0) {
3771 set_register(rd_reg(), rs_u() / rt_u()); 3770 set_register(rd_reg(), rs_u() / rt_u());
3772 } 3771 }
3773 break; 3772 break;
3774 case MOD_OP: 3773 case MOD_OP:
3775 if (rt_u() != 0) { 3774 if (rt_u() != 0) {
3776 set_register(rd_reg(), rs_u() % rt_u()); 3775 set_register(rd_reg(), rs_u() % rt_u());
3777 } 3776 }
3778 break; 3777 break;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3880 case SYNC: 3879 case SYNC:
3881 // TODO(palfia): Ignore sync instruction for now. 3880 // TODO(palfia): Ignore sync instruction for now.
3882 break; 3881 break;
3883 // Conditional moves. 3882 // Conditional moves.
3884 case MOVN: 3883 case MOVN:
3885 if (rt()) { 3884 if (rt()) {
3886 SetResult(rd_reg(), rs()); 3885 SetResult(rd_reg(), rs());
3887 } 3886 }
3888 break; 3887 break;
3889 case MOVCI: { 3888 case MOVCI: {
3890 uint32_t cc = get_instr()->FBccValue(); 3889 uint32_t cc = instr_.FBccValue();
3891 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 3890 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
3892 if (get_instr()->Bit(16)) { // Read Tf bit. 3891 if (instr_.Bit(16)) { // Read Tf bit.
3893 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); 3892 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3894 } else { 3893 } else {
3895 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); 3894 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3896 } 3895 }
3897 break; 3896 break;
3898 } 3897 }
3899 case MOVZ: 3898 case MOVZ:
3900 if (!rt()) { 3899 if (!rt()) {
3901 SetResult(rd_reg(), rs()); 3900 SetResult(rd_reg(), rs());
3902 } 3901 }
3903 break; 3902 break;
3904 default: 3903 default:
3905 UNREACHABLE(); 3904 UNREACHABLE();
3906 } 3905 }
3907 if (do_interrupt) { 3906 if (do_interrupt) {
3908 SoftwareInterrupt(get_instr()); 3907 SoftwareInterrupt();
3909 } 3908 }
3910 } 3909 }
3911 3910
3912 3911
3913 void Simulator::DecodeTypeRegisterSPECIAL2() { 3912 void Simulator::DecodeTypeRegisterSPECIAL2() {
3914 int64_t alu_out; 3913 int64_t alu_out;
3915 switch (get_instr()->FunctionFieldRaw()) { 3914 switch (instr_.FunctionFieldRaw()) {
3916 case MUL: 3915 case MUL:
3917 alu_out = static_cast<int32_t>(rs_u()) * static_cast<int32_t>(rt_u()); 3916 alu_out = static_cast<int32_t>(rs_u()) * static_cast<int32_t>(rt_u());
3918 SetResult(rd_reg(), alu_out); 3917 SetResult(rd_reg(), alu_out);
3919 // HI and LO are UNPREDICTABLE after the operation. 3918 // HI and LO are UNPREDICTABLE after the operation.
3920 set_register(LO, Unpredictable); 3919 set_register(LO, Unpredictable);
3921 set_register(HI, Unpredictable); 3920 set_register(HI, Unpredictable);
3922 break; 3921 break;
3923 case CLZ: 3922 case CLZ:
3924 // MIPS32 spec: If no bits were set in GPR rs(), the result written to 3923 // MIPS32 spec: If no bits were set in GPR rs(), the result written to
3925 // GPR rd is 32. 3924 // GPR rd is 32.
3926 alu_out = base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u())); 3925 alu_out = base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u()));
3927 SetResult(rd_reg(), alu_out); 3926 SetResult(rd_reg(), alu_out);
3928 break; 3927 break;
3929 case DCLZ: 3928 case DCLZ:
3930 // MIPS64 spec: If no bits were set in GPR rs(), the result written to 3929 // MIPS64 spec: If no bits were set in GPR rs(), the result written to
3931 // GPR rd is 64. 3930 // GPR rd is 64.
3932 alu_out = base::bits::CountLeadingZeros64(static_cast<uint64_t>(rs_u())); 3931 alu_out = base::bits::CountLeadingZeros64(static_cast<uint64_t>(rs_u()));
3933 SetResult(rd_reg(), alu_out); 3932 SetResult(rd_reg(), alu_out);
3934 break; 3933 break;
3935 default: 3934 default:
3936 alu_out = 0x12345678; 3935 alu_out = 0x12345678;
3937 UNREACHABLE(); 3936 UNREACHABLE();
3938 } 3937 }
3939 } 3938 }
3940 3939
3941 3940
3942 void Simulator::DecodeTypeRegisterSPECIAL3() { 3941 void Simulator::DecodeTypeRegisterSPECIAL3() {
3943 int64_t alu_out; 3942 int64_t alu_out;
3944 switch (get_instr()->FunctionFieldRaw()) { 3943 switch (instr_.FunctionFieldRaw()) {
3945 case INS: { // Mips64r2 instruction. 3944 case INS: { // Mips64r2 instruction.
3946 // Interpret rd field as 5-bit msb of insert. 3945 // Interpret rd field as 5-bit msb of insert.
3947 uint16_t msb = rd_reg(); 3946 uint16_t msb = rd_reg();
3948 // Interpret sa field as 5-bit lsb of insert. 3947 // Interpret sa field as 5-bit lsb of insert.
3949 uint16_t lsb = sa(); 3948 uint16_t lsb = sa();
3950 uint16_t size = msb - lsb + 1; 3949 uint16_t size = msb - lsb + 1;
3951 uint64_t mask = (1ULL << size) - 1; 3950 uint64_t mask = (1ULL << size) - 1;
3952 alu_out = static_cast<int32_t>((rt_u() & ~(mask << lsb)) | 3951 alu_out = static_cast<int32_t>((rt_u() & ~(mask << lsb)) |
3953 ((rs_u() & mask) << lsb)); 3952 ((rs_u() & mask) << lsb));
3954 SetResult(rt_reg(), alu_out); 3953 SetResult(rt_reg(), alu_out);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4003 uint16_t msb = rd_reg(); 4002 uint16_t msb = rd_reg();
4004 // Interpret sa field as 5-bit lsb of extract. 4003 // Interpret sa field as 5-bit lsb of extract.
4005 uint16_t lsb = sa() + 32; 4004 uint16_t lsb = sa() + 32;
4006 uint16_t size = msb + 1; 4005 uint16_t size = msb + 1;
4007 uint64_t mask = (1ULL << size) - 1; 4006 uint64_t mask = (1ULL << size) - 1;
4008 alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb); 4007 alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
4009 SetResult(rt_reg(), alu_out); 4008 SetResult(rt_reg(), alu_out);
4010 break; 4009 break;
4011 } 4010 }
4012 case BSHFL: { 4011 case BSHFL: {
4013 int32_t sa = get_instr()->SaFieldRaw() >> kSaShift; 4012 int32_t sa = instr_.SaFieldRaw() >> kSaShift;
4014 switch (sa) { 4013 switch (sa) {
4015 case BITSWAP: { 4014 case BITSWAP: {
4016 uint32_t input = static_cast<uint32_t>(rt()); 4015 uint32_t input = static_cast<uint32_t>(rt());
4017 uint32_t output = 0; 4016 uint32_t output = 0;
4018 uint8_t i_byte, o_byte; 4017 uint8_t i_byte, o_byte;
4019 4018
4020 // Reverse the bit in byte for each individual byte 4019 // Reverse the bit in byte for each individual byte
4021 for (int i = 0; i < 4; i++) { 4020 for (int i = 0; i < 4; i++) {
4022 output = output >> 8; 4021 output = output >> 8;
4023 i_byte = input & 0xff; 4022 i_byte = input & 0xff;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4081 4080
4082 // Extending sign 4081 // Extending sign
4083 if (mask & output) { 4082 if (mask & output) {
4084 output |= 0xFFFFFFFF00000000; 4083 output |= 0xFFFFFFFF00000000;
4085 } 4084 }
4086 4085
4087 alu_out = static_cast<int64_t>(output); 4086 alu_out = static_cast<int64_t>(output);
4088 break; 4087 break;
4089 } 4088 }
4090 default: { 4089 default: {
4091 const uint8_t bp2 = get_instr()->Bp2Value(); 4090 const uint8_t bp2 = instr_.Bp2Value();
4092 sa >>= kBp2Bits; 4091 sa >>= kBp2Bits;
4093 switch (sa) { 4092 switch (sa) {
4094 case ALIGN: { 4093 case ALIGN: {
4095 if (bp2 == 0) { 4094 if (bp2 == 0) {
4096 alu_out = static_cast<int32_t>(rt()); 4095 alu_out = static_cast<int32_t>(rt());
4097 } else { 4096 } else {
4098 uint64_t rt_hi = rt() << (8 * bp2); 4097 uint64_t rt_hi = rt() << (8 * bp2);
4099 uint64_t rs_lo = rs() >> (8 * (4 - bp2)); 4098 uint64_t rs_lo = rs() >> (8 * (4 - bp2));
4100 alu_out = static_cast<int32_t>(rt_hi | rs_lo); 4099 alu_out = static_cast<int32_t>(rt_hi | rs_lo);
4101 } 4100 }
4102 break; 4101 break;
4103 } 4102 }
4104 default: 4103 default:
4105 alu_out = 0x12345678; 4104 alu_out = 0x12345678;
4106 UNREACHABLE(); 4105 UNREACHABLE();
4107 break; 4106 break;
4108 } 4107 }
4109 break; 4108 break;
4110 } 4109 }
4111 } 4110 }
4112 SetResult(rd_reg(), alu_out); 4111 SetResult(rd_reg(), alu_out);
4113 break; 4112 break;
4114 } 4113 }
4115 case DBSHFL: { 4114 case DBSHFL: {
4116 int32_t sa = get_instr()->SaFieldRaw() >> kSaShift; 4115 int32_t sa = instr_.SaFieldRaw() >> kSaShift;
4117 switch (sa) { 4116 switch (sa) {
4118 case DBITSWAP: { 4117 case DBITSWAP: {
4119 switch (sa) { 4118 switch (sa) {
4120 case DBITSWAP_SA: { // Mips64r6 4119 case DBITSWAP_SA: { // Mips64r6
4121 uint64_t input = static_cast<uint64_t>(rt()); 4120 uint64_t input = static_cast<uint64_t>(rt());
4122 uint64_t output = 0; 4121 uint64_t output = 0;
4123 uint8_t i_byte, o_byte; 4122 uint8_t i_byte, o_byte;
4124 4123
4125 // Reverse the bit in byte for each individual byte 4124 // Reverse the bit in byte for each individual byte
4126 for (int i = 0; i < 8; i++) { 4125 for (int i = 0; i < 8; i++) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4180 else 4179 else
4181 tmp = tmp << 48; 4180 tmp = tmp << 48;
4182 output = output | tmp; 4181 output = output | tmp;
4183 mask = mask >> 16; 4182 mask = mask >> 16;
4184 } 4183 }
4185 4184
4186 alu_out = static_cast<int64_t>(output); 4185 alu_out = static_cast<int64_t>(output);
4187 break; 4186 break;
4188 } 4187 }
4189 default: { 4188 default: {
4190 const uint8_t bp3 = get_instr()->Bp3Value(); 4189 const uint8_t bp3 = instr_.Bp3Value();
4191 sa >>= kBp3Bits; 4190 sa >>= kBp3Bits;
4192 switch (sa) { 4191 switch (sa) {
4193 case DALIGN: { 4192 case DALIGN: {
4194 if (bp3 == 0) { 4193 if (bp3 == 0) {
4195 alu_out = static_cast<int64_t>(rt()); 4194 alu_out = static_cast<int64_t>(rt());
4196 } else { 4195 } else {
4197 uint64_t rt_hi = rt() << (8 * bp3); 4196 uint64_t rt_hi = rt() << (8 * bp3);
4198 uint64_t rs_lo = rs() >> (8 * (8 - bp3)); 4197 uint64_t rs_lo = rs() >> (8 * (8 - bp3));
4199 alu_out = static_cast<int64_t>(rt_hi | rs_lo); 4198 alu_out = static_cast<int64_t>(rt_hi | rs_lo);
4200 } 4199 }
4201 break; 4200 break;
4202 } 4201 }
4203 default: 4202 default:
4204 alu_out = 0x12345678; 4203 alu_out = 0x12345678;
4205 UNREACHABLE(); 4204 UNREACHABLE();
4206 break; 4205 break;
4207 } 4206 }
4208 break; 4207 break;
4209 } 4208 }
4210 } 4209 }
4211 SetResult(rd_reg(), alu_out); 4210 SetResult(rd_reg(), alu_out);
4212 break; 4211 break;
4213 } 4212 }
4214 default: 4213 default:
4215 UNREACHABLE(); 4214 UNREACHABLE();
4216 } 4215 }
4217 } 4216 }
4218 4217
4219 4218 void Simulator::DecodeTypeRegister() {
4220 void Simulator::DecodeTypeRegister(Instruction* instr) {
4221 set_instr(instr);
4222
4223 // ---------- Execution. 4219 // ---------- Execution.
4224 switch (instr->OpcodeFieldRaw()) { 4220 switch (instr_.OpcodeFieldRaw()) {
4225 case COP1: 4221 case COP1:
4226 DecodeTypeRegisterCOP1(); 4222 DecodeTypeRegisterCOP1();
4227 break; 4223 break;
4228 case COP1X: 4224 case COP1X:
4229 DecodeTypeRegisterCOP1X(); 4225 DecodeTypeRegisterCOP1X();
4230 break; 4226 break;
4231 case SPECIAL: 4227 case SPECIAL:
4232 DecodeTypeRegisterSPECIAL(); 4228 DecodeTypeRegisterSPECIAL();
4233 break; 4229 break;
4234 case SPECIAL2: 4230 case SPECIAL2:
4235 DecodeTypeRegisterSPECIAL2(); 4231 DecodeTypeRegisterSPECIAL2();
4236 break; 4232 break;
4237 case SPECIAL3: 4233 case SPECIAL3:
4238 DecodeTypeRegisterSPECIAL3(); 4234 DecodeTypeRegisterSPECIAL3();
4239 break; 4235 break;
4240 // Unimplemented opcodes raised an error in the configuration step before, 4236 // Unimplemented opcodes raised an error in the configuration step before,
4241 // so we can use the default here to set the destination register in common 4237 // so we can use the default here to set the destination register in common
4242 // cases. 4238 // cases.
4243 default: 4239 default:
4244 UNREACHABLE(); 4240 UNREACHABLE();
4245 } 4241 }
4246 } 4242 }
4247 4243
4248 4244
4249 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). 4245 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc).
4250 void Simulator::DecodeTypeImmediate(Instruction* instr) { 4246 void Simulator::DecodeTypeImmediate() {
4251 // Instruction fields. 4247 // Instruction fields.
4252 Opcode op = instr->OpcodeFieldRaw(); 4248 Opcode op = instr_.OpcodeFieldRaw();
4253 int32_t rs_reg = instr->RsValue(); 4249 int32_t rs_reg = instr_.RsValue();
4254 int64_t rs = get_register(instr->RsValue()); 4250 int64_t rs = get_register(instr_.RsValue());
4255 uint64_t rs_u = static_cast<uint64_t>(rs); 4251 uint64_t rs_u = static_cast<uint64_t>(rs);
4256 int32_t rt_reg = instr->RtValue(); // Destination register. 4252 int32_t rt_reg = instr_.RtValue(); // Destination register.
4257 int64_t rt = get_register(rt_reg); 4253 int64_t rt = get_register(rt_reg);
4258 int16_t imm16 = instr->Imm16Value(); 4254 int16_t imm16 = instr_.Imm16Value();
4259 int32_t imm18 = instr->Imm18Value(); 4255 int32_t imm18 = instr_.Imm18Value();
4260 4256
4261 int32_t ft_reg = instr->FtValue(); // Destination register. 4257 int32_t ft_reg = instr_.FtValue(); // Destination register.
4262 4258
4263 // Zero extended immediate. 4259 // Zero extended immediate.
4264 uint64_t oe_imm16 = 0xffff & imm16; 4260 uint64_t oe_imm16 = 0xffff & imm16;
4265 // Sign extended immediate. 4261 // Sign extended immediate.
4266 int64_t se_imm16 = imm16; 4262 int64_t se_imm16 = imm16;
4267 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0); 4263 int64_t se_imm18 = imm18 | ((imm18 & 0x20000) ? 0xfffffffffffc0000 : 0);
4268 4264
4269 // Next pc. 4265 // Next pc.
4270 int64_t next_pc = bad_ra; 4266 int64_t next_pc = bad_ra;
4271 4267
4272 // Used for conditional branch instructions. 4268 // Used for conditional branch instructions.
4273 bool execute_branch_delay_instruction = false; 4269 bool execute_branch_delay_instruction = false;
4274 4270
4275 // Used for arithmetic instructions. 4271 // Used for arithmetic instructions.
4276 int64_t alu_out = 0; 4272 int64_t alu_out = 0;
4277 4273
4278 // Used for memory instructions. 4274 // Used for memory instructions.
4279 int64_t addr = 0x0; 4275 int64_t addr = 0x0;
4280 // Alignment for 32-bit integers used in LWL, LWR, etc. 4276 // Alignment for 32-bit integers used in LWL, LWR, etc.
4281 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; 4277 const int kInt32AlignmentMask = sizeof(uint32_t) - 1;
4282 // Alignment for 64-bit integers used in LDL, LDR, etc. 4278 // Alignment for 64-bit integers used in LDL, LDR, etc.
4283 const int kInt64AlignmentMask = sizeof(uint64_t) - 1; 4279 const int kInt64AlignmentMask = sizeof(uint64_t) - 1;
4284 4280
4285 // Branch instructions common part. 4281 // Branch instructions common part.
4286 auto BranchAndLinkHelper = [this, instr, &next_pc, 4282 auto BranchAndLinkHelper =
4287 &execute_branch_delay_instruction]( 4283 [this, &next_pc, &execute_branch_delay_instruction](bool do_branch) {
4288 bool do_branch) { 4284 execute_branch_delay_instruction = true;
4289 execute_branch_delay_instruction = true; 4285 int64_t current_pc = get_pc();
4290 int64_t current_pc = get_pc(); 4286 if (do_branch) {
4291 if (do_branch) { 4287 int16_t imm16 = instr_.Imm16Value();
4292 int16_t imm16 = instr->Imm16Value(); 4288 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4293 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 4289 set_register(31, current_pc + 2 * Instruction::kInstrSize);
4294 set_register(31, current_pc + 2 * Instruction::kInstrSize); 4290 } else {
4295 } else { 4291 next_pc = current_pc + 2 * Instruction::kInstrSize;
4296 next_pc = current_pc + 2 * Instruction::kInstrSize; 4292 }
4297 } 4293 };
4298 };
4299 4294
4300 auto BranchHelper = [this, instr, &next_pc, 4295 auto BranchHelper = [this, &next_pc,
4301 &execute_branch_delay_instruction](bool do_branch) { 4296 &execute_branch_delay_instruction](bool do_branch) {
4302 execute_branch_delay_instruction = true; 4297 execute_branch_delay_instruction = true;
4303 int64_t current_pc = get_pc(); 4298 int64_t current_pc = get_pc();
4304 if (do_branch) { 4299 if (do_branch) {
4305 int16_t imm16 = instr->Imm16Value(); 4300 int16_t imm16 = instr_.Imm16Value();
4306 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 4301 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4307 } else { 4302 } else {
4308 next_pc = current_pc + 2 * Instruction::kInstrSize; 4303 next_pc = current_pc + 2 * Instruction::kInstrSize;
4309 } 4304 }
4310 }; 4305 };
4311 4306
4312 auto BranchAndLinkCompactHelper = [this, instr, &next_pc](bool do_branch, 4307 auto BranchAndLinkCompactHelper = [this, &next_pc](bool do_branch, int bits) {
4313 int bits) {
4314 int64_t current_pc = get_pc(); 4308 int64_t current_pc = get_pc();
4315 CheckForbiddenSlot(current_pc); 4309 CheckForbiddenSlot(current_pc);
4316 if (do_branch) { 4310 if (do_branch) {
4317 int32_t imm = instr->ImmValue(bits); 4311 int32_t imm = instr_.ImmValue(bits);
4318 imm <<= 32 - bits; 4312 imm <<= 32 - bits;
4319 imm >>= 32 - bits; 4313 imm >>= 32 - bits;
4320 next_pc = current_pc + (imm << 2) + Instruction::kInstrSize; 4314 next_pc = current_pc + (imm << 2) + Instruction::kInstrSize;
4321 set_register(31, current_pc + Instruction::kInstrSize); 4315 set_register(31, current_pc + Instruction::kInstrSize);
4322 } 4316 }
4323 }; 4317 };
4324 4318
4325 auto BranchCompactHelper = [&next_pc, this, instr](bool do_branch, int bits) { 4319 auto BranchCompactHelper = [this, &next_pc](bool do_branch, int bits) {
4326 int64_t current_pc = get_pc(); 4320 int64_t current_pc = get_pc();
4327 CheckForbiddenSlot(current_pc); 4321 CheckForbiddenSlot(current_pc);
4328 if (do_branch) { 4322 if (do_branch) {
4329 int32_t imm = instr->ImmValue(bits); 4323 int32_t imm = instr_.ImmValue(bits);
4330 imm <<= 32 - bits; 4324 imm <<= 32 - bits;
4331 imm >>= 32 - bits; 4325 imm >>= 32 - bits;
4332 next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize; 4326 next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize;
4333 } 4327 }
4334 }; 4328 };
4335 4329
4336 switch (op) { 4330 switch (op) {
4337 // ------------- COP1. Coprocessor instructions. 4331 // ------------- COP1. Coprocessor instructions.
4338 case COP1: 4332 case COP1:
4339 switch (instr->RsFieldRaw()) { 4333 switch (instr_.RsFieldRaw()) {
4340 case BC1: { // Branch on coprocessor condition. 4334 case BC1: { // Branch on coprocessor condition.
4341 uint32_t cc = instr->FBccValue(); 4335 uint32_t cc = instr_.FBccValue();
4342 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 4336 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
4343 uint32_t cc_value = test_fcsr_bit(fcsr_cc); 4337 uint32_t cc_value = test_fcsr_bit(fcsr_cc);
4344 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; 4338 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value;
4345 BranchHelper(do_branch); 4339 BranchHelper(do_branch);
4346 break; 4340 break;
4347 } 4341 }
4348 case BC1EQZ: 4342 case BC1EQZ:
4349 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); 4343 BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
4350 break; 4344 break;
4351 case BC1NEZ: 4345 case BC1NEZ:
4352 BranchHelper(get_fpu_register(ft_reg) & 0x1); 4346 BranchHelper(get_fpu_register(ft_reg) & 0x1);
4353 break; 4347 break;
4354 default: 4348 default:
4355 UNREACHABLE(); 4349 UNREACHABLE();
4356 } 4350 }
4357 break; 4351 break;
4358 // ------------- REGIMM class. 4352 // ------------- REGIMM class.
4359 case REGIMM: 4353 case REGIMM:
4360 switch (instr->RtFieldRaw()) { 4354 switch (instr_.RtFieldRaw()) {
4361 case BLTZ: 4355 case BLTZ:
4362 BranchHelper(rs < 0); 4356 BranchHelper(rs < 0);
4363 break; 4357 break;
4364 case BGEZ: 4358 case BGEZ:
4365 BranchHelper(rs >= 0); 4359 BranchHelper(rs >= 0);
4366 break; 4360 break;
4367 case BLTZAL: 4361 case BLTZAL:
4368 BranchAndLinkHelper(rs < 0); 4362 BranchAndLinkHelper(rs < 0);
4369 break; 4363 break;
4370 case BGEZAL: 4364 case BGEZAL:
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
4568 case DAUI: 4562 case DAUI:
4569 DCHECK(kArchVariant == kMips64r6); 4563 DCHECK(kArchVariant == kMips64r6);
4570 DCHECK(rs_reg != 0); 4564 DCHECK(rs_reg != 0);
4571 SetResult(rt_reg, rs + (se_imm16 << 16)); 4565 SetResult(rt_reg, rs + (se_imm16 << 16));
4572 break; 4566 break;
4573 // ------------- Memory instructions. 4567 // ------------- Memory instructions.
4574 case LB: 4568 case LB:
4575 set_register(rt_reg, ReadB(rs + se_imm16)); 4569 set_register(rt_reg, ReadB(rs + se_imm16));
4576 break; 4570 break;
4577 case LH: 4571 case LH:
4578 set_register(rt_reg, ReadH(rs + se_imm16, instr)); 4572 set_register(rt_reg, ReadH(rs + se_imm16, instr_.instr()));
4579 break; 4573 break;
4580 case LWL: { 4574 case LWL: {
4581 // al_offset is offset of the effective address within an aligned word. 4575 // al_offset is offset of the effective address within an aligned word.
4582 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4576 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4583 uint8_t byte_shift = kInt32AlignmentMask - al_offset; 4577 uint8_t byte_shift = kInt32AlignmentMask - al_offset;
4584 uint32_t mask = (1 << byte_shift * 8) - 1; 4578 uint32_t mask = (1 << byte_shift * 8) - 1;
4585 addr = rs + se_imm16 - al_offset; 4579 addr = rs + se_imm16 - al_offset;
4586 int32_t val = ReadW(addr, instr); 4580 int32_t val = ReadW(addr, instr_.instr());
4587 val <<= byte_shift * 8; 4581 val <<= byte_shift * 8;
4588 val |= rt & mask; 4582 val |= rt & mask;
4589 set_register(rt_reg, static_cast<int64_t>(val)); 4583 set_register(rt_reg, static_cast<int64_t>(val));
4590 break; 4584 break;
4591 } 4585 }
4592 case LW: 4586 case LW:
4593 set_register(rt_reg, ReadW(rs + se_imm16, instr)); 4587 set_register(rt_reg, ReadW(rs + se_imm16, instr_.instr()));
4594 break; 4588 break;
4595 case LWU: 4589 case LWU:
4596 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); 4590 set_register(rt_reg, ReadWU(rs + se_imm16, instr_.instr()));
4597 break; 4591 break;
4598 case LD: 4592 case LD:
4599 set_register(rt_reg, Read2W(rs + se_imm16, instr)); 4593 set_register(rt_reg, Read2W(rs + se_imm16, instr_.instr()));
4600 break; 4594 break;
4601 case LBU: 4595 case LBU:
4602 set_register(rt_reg, ReadBU(rs + se_imm16)); 4596 set_register(rt_reg, ReadBU(rs + se_imm16));
4603 break; 4597 break;
4604 case LHU: 4598 case LHU:
4605 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); 4599 set_register(rt_reg, ReadHU(rs + se_imm16, instr_.instr()));
4606 break; 4600 break;
4607 case LWR: { 4601 case LWR: {
4608 // al_offset is offset of the effective address within an aligned word. 4602 // al_offset is offset of the effective address within an aligned word.
4609 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4603 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4610 uint8_t byte_shift = kInt32AlignmentMask - al_offset; 4604 uint8_t byte_shift = kInt32AlignmentMask - al_offset;
4611 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; 4605 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
4612 addr = rs + se_imm16 - al_offset; 4606 addr = rs + se_imm16 - al_offset;
4613 alu_out = ReadW(addr, instr); 4607 alu_out = ReadW(addr, instr_.instr());
4614 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; 4608 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
4615 alu_out |= rt & mask; 4609 alu_out |= rt & mask;
4616 set_register(rt_reg, alu_out); 4610 set_register(rt_reg, alu_out);
4617 break; 4611 break;
4618 } 4612 }
4619 case LDL: { 4613 case LDL: {
4620 // al_offset is offset of the effective address within an aligned word. 4614 // al_offset is offset of the effective address within an aligned word.
4621 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; 4615 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
4622 uint8_t byte_shift = kInt64AlignmentMask - al_offset; 4616 uint8_t byte_shift = kInt64AlignmentMask - al_offset;
4623 uint64_t mask = (1UL << byte_shift * 8) - 1; 4617 uint64_t mask = (1UL << byte_shift * 8) - 1;
4624 addr = rs + se_imm16 - al_offset; 4618 addr = rs + se_imm16 - al_offset;
4625 alu_out = Read2W(addr, instr); 4619 alu_out = Read2W(addr, instr_.instr());
4626 alu_out <<= byte_shift * 8; 4620 alu_out <<= byte_shift * 8;
4627 alu_out |= rt & mask; 4621 alu_out |= rt & mask;
4628 set_register(rt_reg, alu_out); 4622 set_register(rt_reg, alu_out);
4629 break; 4623 break;
4630 } 4624 }
4631 case LDR: { 4625 case LDR: {
4632 // al_offset is offset of the effective address within an aligned word. 4626 // al_offset is offset of the effective address within an aligned word.
4633 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; 4627 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
4634 uint8_t byte_shift = kInt64AlignmentMask - al_offset; 4628 uint8_t byte_shift = kInt64AlignmentMask - al_offset;
4635 uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL; 4629 uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL;
4636 addr = rs + se_imm16 - al_offset; 4630 addr = rs + se_imm16 - al_offset;
4637 alu_out = Read2W(addr, instr); 4631 alu_out = Read2W(addr, instr_.instr());
4638 alu_out = alu_out >> al_offset * 8; 4632 alu_out = alu_out >> al_offset * 8;
4639 alu_out |= rt & mask; 4633 alu_out |= rt & mask;
4640 set_register(rt_reg, alu_out); 4634 set_register(rt_reg, alu_out);
4641 break; 4635 break;
4642 } 4636 }
4643 case SB: 4637 case SB:
4644 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); 4638 WriteB(rs + se_imm16, static_cast<int8_t>(rt));
4645 break; 4639 break;
4646 case SH: 4640 case SH:
4647 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); 4641 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr_.instr());
4648 break; 4642 break;
4649 case SWL: { 4643 case SWL: {
4650 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4644 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4651 uint8_t byte_shift = kInt32AlignmentMask - al_offset; 4645 uint8_t byte_shift = kInt32AlignmentMask - al_offset;
4652 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; 4646 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
4653 addr = rs + se_imm16 - al_offset; 4647 addr = rs + se_imm16 - al_offset;
4654 uint64_t mem_value = ReadW(addr, instr) & mask; 4648 uint64_t mem_value = ReadW(addr, instr_.instr()) & mask;
4655 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8; 4649 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
4656 WriteW(addr, static_cast<int32_t>(mem_value), instr); 4650 WriteW(addr, static_cast<int32_t>(mem_value), instr_.instr());
4657 break; 4651 break;
4658 } 4652 }
4659 case SW: 4653 case SW:
4660 WriteW(rs + se_imm16, static_cast<int32_t>(rt), instr); 4654 WriteW(rs + se_imm16, static_cast<int32_t>(rt), instr_.instr());
4661 break; 4655 break;
4662 case SD: 4656 case SD:
4663 Write2W(rs + se_imm16, rt, instr); 4657 Write2W(rs + se_imm16, rt, instr_.instr());
4664 break; 4658 break;
4665 case SWR: { 4659 case SWR: {
4666 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; 4660 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask;
4667 uint32_t mask = (1 << al_offset * 8) - 1; 4661 uint32_t mask = (1 << al_offset * 8) - 1;
4668 addr = rs + se_imm16 - al_offset; 4662 addr = rs + se_imm16 - al_offset;
4669 uint64_t mem_value = ReadW(addr, instr); 4663 uint64_t mem_value = ReadW(addr, instr_.instr());
4670 mem_value = (rt << al_offset * 8) | (mem_value & mask); 4664 mem_value = (rt << al_offset * 8) | (mem_value & mask);
4671 WriteW(addr, static_cast<int32_t>(mem_value), instr); 4665 WriteW(addr, static_cast<int32_t>(mem_value), instr_.instr());
4672 break; 4666 break;
4673 } 4667 }
4674 case SDL: { 4668 case SDL: {
4675 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; 4669 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
4676 uint8_t byte_shift = kInt64AlignmentMask - al_offset; 4670 uint8_t byte_shift = kInt64AlignmentMask - al_offset;
4677 uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0; 4671 uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0;
4678 addr = rs + se_imm16 - al_offset; 4672 addr = rs + se_imm16 - al_offset;
4679 uint64_t mem_value = Read2W(addr, instr) & mask; 4673 uint64_t mem_value = Read2W(addr, instr_.instr()) & mask;
4680 mem_value |= rt >> byte_shift * 8; 4674 mem_value |= rt >> byte_shift * 8;
4681 Write2W(addr, mem_value, instr); 4675 Write2W(addr, mem_value, instr_.instr());
4682 break; 4676 break;
4683 } 4677 }
4684 case SDR: { 4678 case SDR: {
4685 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; 4679 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
4686 uint64_t mask = (1UL << al_offset * 8) - 1; 4680 uint64_t mask = (1UL << al_offset * 8) - 1;
4687 addr = rs + se_imm16 - al_offset; 4681 addr = rs + se_imm16 - al_offset;
4688 uint64_t mem_value = Read2W(addr, instr); 4682 uint64_t mem_value = Read2W(addr, instr_.instr());
4689 mem_value = (rt << al_offset * 8) | (mem_value & mask); 4683 mem_value = (rt << al_offset * 8) | (mem_value & mask);
4690 Write2W(addr, mem_value, instr); 4684 Write2W(addr, mem_value, instr_.instr());
4691 break; 4685 break;
4692 } 4686 }
4693 case LWC1: 4687 case LWC1:
4694 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. 4688 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits.
4695 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); 4689 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr()));
4696 break; 4690 break;
4697 case LDC1: 4691 case LDC1:
4698 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); 4692 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr()));
4699 break; 4693 break;
4700 case SWC1: { 4694 case SWC1: {
4701 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); 4695 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg));
4702 WriteW(rs + se_imm16, alu_out_32, instr); 4696 WriteW(rs + se_imm16, alu_out_32, instr_.instr());
4703 break; 4697 break;
4704 } 4698 }
4705 case SDC1: 4699 case SDC1:
4706 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); 4700 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr());
4707 break; 4701 break;
4708 // ------------- PC-Relative instructions. 4702 // ------------- PC-Relative instructions.
4709 case PCREL: { 4703 case PCREL: {
4710 // rt field: checking 5-bits. 4704 // rt field: checking 5-bits.
4711 int32_t imm21 = instr->Imm21Value(); 4705 int32_t imm21 = instr_.Imm21Value();
4712 int64_t current_pc = get_pc(); 4706 int64_t current_pc = get_pc();
4713 uint8_t rt = (imm21 >> kImm16Bits); 4707 uint8_t rt = (imm21 >> kImm16Bits);
4714 switch (rt) { 4708 switch (rt) {
4715 case ALUIPC: 4709 case ALUIPC:
4716 addr = current_pc + (se_imm16 << 16); 4710 addr = current_pc + (se_imm16 << 16);
4717 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; 4711 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4718 break; 4712 break;
4719 case AUIPC: 4713 case AUIPC:
4720 alu_out = current_pc + (se_imm16 << 16); 4714 alu_out = current_pc + (se_imm16 << 16);
4721 break; 4715 break;
4722 default: { 4716 default: {
4723 int32_t imm19 = instr->Imm19Value(); 4717 int32_t imm19 = instr_.Imm19Value();
4724 // rt field: checking the most significant 3-bits. 4718 // rt field: checking the most significant 3-bits.
4725 rt = (imm21 >> kImm18Bits); 4719 rt = (imm21 >> kImm18Bits);
4726 switch (rt) { 4720 switch (rt) {
4727 case LDPC: 4721 case LDPC:
4728 addr = 4722 addr =
4729 (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3); 4723 (current_pc & static_cast<int64_t>(~0x7)) + (se_imm18 << 3);
4730 alu_out = Read2W(addr, instr); 4724 alu_out = Read2W(addr, instr_.instr());
4731 break; 4725 break;
4732 default: { 4726 default: {
4733 // rt field: checking the most significant 2-bits. 4727 // rt field: checking the most significant 2-bits.
4734 rt = (imm21 >> kImm19Bits); 4728 rt = (imm21 >> kImm19Bits);
4735 switch (rt) { 4729 switch (rt) {
4736 case LWUPC: { 4730 case LWUPC: {
4737 // Set sign. 4731 // Set sign.
4738 imm19 <<= (kOpcodeBits + kRsBits + 2); 4732 imm19 <<= (kOpcodeBits + kRsBits + 2);
4739 imm19 >>= (kOpcodeBits + kRsBits + 2); 4733 imm19 >>= (kOpcodeBits + kRsBits + 2);
4740 addr = current_pc + (imm19 << 2); 4734 addr = current_pc + (imm19 << 2);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4784 } 4778 }
4785 4779
4786 // If needed update pc after the branch delay execution. 4780 // If needed update pc after the branch delay execution.
4787 if (next_pc != bad_ra) { 4781 if (next_pc != bad_ra) {
4788 set_pc(next_pc); 4782 set_pc(next_pc);
4789 } 4783 }
4790 } 4784 }
4791 4785
4792 4786
4793 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). 4787 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
4794 void Simulator::DecodeTypeJump(Instruction* instr) { 4788 void Simulator::DecodeTypeJump() {
4789 SimInstruction simInstr = instr_;
Ilija.Pavlovic1 2016/09/29 10:13:40 Why this variable is defined? instr_ is the same t
balazs.kilvady 2016/09/29 10:57:41 A copy of the current instruction is needed here a
Ilija.Pavlovic1 2016/09/29 13:15:33 Acknowledged.
4795 // Get current pc. 4790 // Get current pc.
4796 int64_t current_pc = get_pc(); 4791 int64_t current_pc = get_pc();
4797 // Get unchanged bits of pc. 4792 // Get unchanged bits of pc.
4798 int64_t pc_high_bits = current_pc & 0xfffffffff0000000; 4793 int64_t pc_high_bits = current_pc & 0xfffffffff0000000;
4799 // Next pc. 4794 // Next pc.
4800 int64_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); 4795 int64_t next_pc = pc_high_bits | (simInstr.Imm26Value() << 2);
4801 4796
4802 // Execute branch delay slot. 4797 // Execute branch delay slot.
4803 // We don't check for end_sim_pc. First it should not be met as the current pc 4798 // We don't check for end_sim_pc. First it should not be met as the current pc
4804 // is valid. Secondly a jump should always execute its branch delay slot. 4799 // is valid. Secondly a jump should always execute its branch delay slot.
4805 Instruction* branch_delay_instr = 4800 Instruction* branch_delay_instr =
4806 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); 4801 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
4807 BranchDelayInstructionDecode(branch_delay_instr); 4802 BranchDelayInstructionDecode(branch_delay_instr);
4808 4803
4809 // Update pc and ra if necessary. 4804 // Update pc and ra if necessary.
4810 // Do this after the branch delay execution. 4805 // Do this after the branch delay execution.
4811 if (instr->IsLinkingInstruction()) { 4806 if (simInstr.IsLinkingInstruction()) {
4812 set_register(31, current_pc + 2 * Instruction::kInstrSize); 4807 set_register(31, current_pc + 2 * Instruction::kInstrSize);
4813 } 4808 }
4814 set_pc(next_pc); 4809 set_pc(next_pc);
4815 pc_modified_ = true; 4810 pc_modified_ = true;
4816 } 4811 }
4817 4812
4818 4813
4819 // Executes the current instruction. 4814 // Executes the current instruction.
4820 void Simulator::InstructionDecode(Instruction* instr) { 4815 void Simulator::InstructionDecode(Instruction* instr) {
4821 if (v8::internal::FLAG_check_icache) { 4816 if (v8::internal::FLAG_check_icache) {
4822 CheckICache(isolate_->simulator_i_cache(), instr); 4817 CheckICache(isolate_->simulator_i_cache(), instr);
4823 } 4818 }
4824 pc_modified_ = false; 4819 pc_modified_ = false;
4825 4820
4826 v8::internal::EmbeddedVector<char, 256> buffer; 4821 v8::internal::EmbeddedVector<char, 256> buffer;
4827 4822
4828 if (::v8::internal::FLAG_trace_sim) { 4823 if (::v8::internal::FLAG_trace_sim) {
4829 SNPrintF(trace_buf_, " "); 4824 SNPrintF(trace_buf_, " ");
4830 disasm::NameConverter converter; 4825 disasm::NameConverter converter;
4831 disasm::Disassembler dasm(converter); 4826 disasm::Disassembler dasm(converter);
4832 // Use a reasonably large buffer. 4827 // Use a reasonably large buffer.
4833 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); 4828 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
4834 } 4829 }
4835 4830
4836 switch (instr->InstructionType(Instruction::TypeChecks::EXTRA)) { 4831 instr_ = instr;
Ilija.Pavlovic1 2016/09/29 10:13:39 Was it possible to do the same thing as for Decode
balazs.kilvady 2016/09/29 10:57:41 No, this function is the main entry point for proc
Ilija.Pavlovic1 2016/09/29 13:15:33 Acknowledged.
4832 switch (instr_.InstructionType()) {
4837 case Instruction::kRegisterType: 4833 case Instruction::kRegisterType:
4838 DecodeTypeRegister(instr); 4834 DecodeTypeRegister();
4839 break; 4835 break;
4840 case Instruction::kImmediateType: 4836 case Instruction::kImmediateType:
4841 DecodeTypeImmediate(instr); 4837 DecodeTypeImmediate();
4842 break; 4838 break;
4843 case Instruction::kJumpType: 4839 case Instruction::kJumpType:
4844 DecodeTypeJump(instr); 4840 DecodeTypeJump();
4845 break; 4841 break;
4846 default: 4842 default:
4847 UNSUPPORTED(); 4843 UNSUPPORTED();
4848 } 4844 }
4849 4845
4850 if (::v8::internal::FLAG_trace_sim) { 4846 if (::v8::internal::FLAG_trace_sim) {
4851 PrintF(" 0x%08" PRIxPTR " %-44s %s\n", 4847 PrintF(" 0x%08" PRIxPTR " %-44s %s\n",
4852 reinterpret_cast<intptr_t>(instr), buffer.start(), 4848 reinterpret_cast<intptr_t>(instr), buffer.start(),
4853 trace_buf_.start()); 4849 trace_buf_.start());
4854 } 4850 }
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
5053 } 5049 }
5054 5050
5055 5051
5056 #undef UNSUPPORTED 5052 #undef UNSUPPORTED
5057 } // namespace internal 5053 } // namespace internal
5058 } // namespace v8 5054 } // namespace v8
5059 5055
5060 #endif // USE_SIMULATOR 5056 #endif // USE_SIMULATOR
5061 5057
5062 #endif // V8_TARGET_ARCH_MIPS64 5058 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« src/mips64/constants-mips64.h ('K') | « src/mips64/simulator-mips64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698