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

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

Issue 1349403003: MIPS: Improve performance of simulator in debug mode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix after rebase. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/mips/simulator-mips.h ('K') | « src/mips/simulator-mips.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_MIPS 10 #if V8_TARGET_ARCH_MIPS
(...skipping 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0); 1922 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
1923 typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, void* arg1); 1923 typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, void* arg1);
1924 1924
1925 // This signature supports direct call to accessor getter callback. 1925 // This signature supports direct call to accessor getter callback.
1926 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1); 1926 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
1927 typedef void (*SimulatorRuntimeProfilingGetterCall)( 1927 typedef void (*SimulatorRuntimeProfilingGetterCall)(
1928 int32_t arg0, int32_t arg1, void* arg2); 1928 int32_t arg0, int32_t arg1, void* arg2);
1929 1929
1930 // Software interrupt instructions are used by the simulator to call into the 1930 // Software interrupt instructions are used by the simulator to call into the
1931 // C-based V8 runtime. They are also used for debugging with simulator. 1931 // C-based V8 runtime. They are also used for debugging with simulator.
1932 void Simulator::SoftwareInterrupt(Instruction* instr) { 1932 void Simulator::SoftwareInterrupt() {
1933 // There are several instructions that could get us here, 1933 // There are several instructions that could get us here,
1934 // the break_ instruction, or several variants of traps. All 1934 // the break_ instruction, or several variants of traps. All
1935 // Are "SPECIAL" class opcode, and are distinuished by function. 1935 // Are "SPECIAL" class opcode, and are distinuished by function.
1936 int32_t func = instr->FunctionFieldRaw(); 1936 int32_t func = instr_.FunctionFieldRaw();
1937 uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1; 1937 uint32_t code = (func == BREAK) ? instr_.Bits(25, 6) : -1;
1938 1938
1939 // We first check if we met a call_rt_redirected. 1939 // We first check if we met a call_rt_redirected.
1940 if (instr->InstructionBits() == rtCallRedirInstr) { 1940 if (instr_.InstructionBits() == rtCallRedirInstr) {
1941 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1941 Redirection* redirection =
1942 Redirection::FromSwiInstruction(instr_.instr());
1942 int32_t arg0 = get_register(a0); 1943 int32_t arg0 = get_register(a0);
1943 int32_t arg1 = get_register(a1); 1944 int32_t arg1 = get_register(a1);
1944 int32_t arg2 = get_register(a2); 1945 int32_t arg2 = get_register(a2);
1945 int32_t arg3 = get_register(a3); 1946 int32_t arg3 = get_register(a3);
1946 1947
1947 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); 1948 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1948 // Args 4 and 5 are on the stack after the reserved space for args 0..3. 1949 // Args 4 and 5 are on the stack after the reserved space for args 0..3.
1949 int32_t arg4 = stack_pointer[4]; 1950 int32_t arg4 = stack_pointer[4];
1950 int32_t arg5 = stack_pointer[5]; 1951 int32_t arg5 = stack_pointer[5];
1951 1952
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0)); 2167 PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0));
2167 } 2168 }
2168 set_register(ra, saved_ra); 2169 set_register(ra, saved_ra);
2169 set_pc(get_register(ra)); 2170 set_pc(get_register(ra));
2170 2171
2171 } else if (func == BREAK && code <= kMaxStopCode) { 2172 } else if (func == BREAK && code <= kMaxStopCode) {
2172 if (IsWatchpoint(code)) { 2173 if (IsWatchpoint(code)) {
2173 PrintWatchpoint(code); 2174 PrintWatchpoint(code);
2174 } else { 2175 } else {
2175 IncreaseStopCounter(code); 2176 IncreaseStopCounter(code);
2176 HandleStop(code, instr); 2177 HandleStop(code, instr_.instr());
2177 } 2178 }
2178 } else { 2179 } else {
2179 // All remaining break_ codes, and all traps are handled here. 2180 // All remaining break_ codes, and all traps are handled here.
2180 MipsDebugger dbg(this); 2181 MipsDebugger dbg(this);
2181 dbg.Debug(); 2182 dbg.Debug();
2182 } 2183 }
2183 } 2184 }
2184 2185
2185 2186
2186 // Stop helper functions. 2187 // Stop helper functions.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 return result; 2410 return result;
2410 } 2411 }
2411 2412
2412 // Handle execution based on instruction types. 2413 // Handle execution based on instruction types.
2413 2414
2414 void Simulator::DecodeTypeRegisterDRsType() { 2415 void Simulator::DecodeTypeRegisterDRsType() {
2415 double ft, fs, fd; 2416 double ft, fs, fd;
2416 uint32_t cc, fcsr_cc; 2417 uint32_t cc, fcsr_cc;
2417 int64_t i64; 2418 int64_t i64;
2418 fs = get_fpu_register_double(fs_reg()); 2419 fs = get_fpu_register_double(fs_reg());
2419 ft = (get_instr()->FunctionFieldRaw() != MOVF) 2420 ft = (instr_.FunctionFieldRaw() != MOVF)
2420 ? get_fpu_register_double(ft_reg()) 2421 ? get_fpu_register_double(ft_reg())
2421 : 0.0; 2422 : 0.0;
2422 fd = get_fpu_register_double(fd_reg()); 2423 fd = get_fpu_register_double(fd_reg());
2423 int64_t ft_int = bit_cast<int64_t>(ft); 2424 int64_t ft_int = bit_cast<int64_t>(ft);
2424 int64_t fd_int = bit_cast<int64_t>(fd); 2425 int64_t fd_int = bit_cast<int64_t>(fd);
2425 cc = get_instr()->FCccValue(); 2426 cc = instr_.FCccValue();
2426 fcsr_cc = get_fcsr_condition_bit(cc); 2427 fcsr_cc = get_fcsr_condition_bit(cc);
2427 switch (get_instr()->FunctionFieldRaw()) { 2428 switch (instr_.FunctionFieldRaw()) {
2428 case RINT: { 2429 case RINT: {
2429 DCHECK(IsMipsArchVariant(kMips32r6)); 2430 DCHECK(IsMipsArchVariant(kMips32r6));
2430 double result, temp, temp_result; 2431 double result, temp, temp_result;
2431 double upper = std::ceil(fs); 2432 double upper = std::ceil(fs);
2432 double lower = std::floor(fs); 2433 double lower = std::floor(fs);
2433 switch (get_fcsr_rounding_mode()) { 2434 switch (get_fcsr_rounding_mode()) {
2434 case kRoundToNearest: 2435 case kRoundToNearest:
2435 if (upper - fs < fs - lower) { 2436 if (upper - fs < fs - lower) {
2436 result = upper; 2437 result = upper;
2437 } else if (upper - fs > fs - lower) { 2438 } else if (upper - fs > fs - lower) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 break; 2477 break;
2477 case MOVZ_C: { 2478 case MOVZ_C: {
2478 DCHECK(IsMipsArchVariant(kMips32r2)); 2479 DCHECK(IsMipsArchVariant(kMips32r2));
2479 if (rt() == 0) { 2480 if (rt() == 0) {
2480 set_fpu_register_double(fd_reg(), fs); 2481 set_fpu_register_double(fd_reg(), fs);
2481 } 2482 }
2482 break; 2483 break;
2483 } 2484 }
2484 case MOVN_C: { 2485 case MOVN_C: {
2485 DCHECK(IsMipsArchVariant(kMips32r2)); 2486 DCHECK(IsMipsArchVariant(kMips32r2));
2486 int32_t rt_reg = get_instr()->RtValue(); 2487 int32_t rt_reg = instr_.RtValue();
2487 int32_t rt = get_register(rt_reg); 2488 int32_t rt = get_register(rt_reg);
2488 if (rt != 0) { 2489 if (rt != 0) {
2489 set_fpu_register_double(fd_reg(), fs); 2490 set_fpu_register_double(fd_reg(), fs);
2490 } 2491 }
2491 break; 2492 break;
2492 } 2493 }
2493 case MOVF: { 2494 case MOVF: {
2494 // Same function field for MOVT.D and MOVF.D 2495 // Same function field for MOVT.D and MOVF.D
2495 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 2496 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
2496 ft_cc = get_fcsr_condition_bit(ft_cc); 2497 ft_cc = get_fcsr_condition_bit(ft_cc);
2497 if (get_instr()->Bit(16)) { // Read Tf bit. 2498 if (instr_.Bit(16)) { // Read Tf bit.
2498 // MOVT.D 2499 // MOVT.D
2499 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2500 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2500 } else { 2501 } else {
2501 // MOVF.D 2502 // MOVF.D
2502 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2503 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2503 } 2504 }
2504 break; 2505 break;
2505 } 2506 }
2506 case MIN: 2507 case MIN:
2507 DCHECK(IsMipsArchVariant(kMips32r6)); 2508 DCHECK(IsMipsArchVariant(kMips32r6));
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 default: 2803 default:
2803 UNREACHABLE(); 2804 UNREACHABLE();
2804 } 2805 }
2805 } 2806 }
2806 2807
2807 2808
2808 void Simulator::DecodeTypeRegisterWRsType() { 2809 void Simulator::DecodeTypeRegisterWRsType() {
2809 float fs = get_fpu_register_float(fs_reg()); 2810 float fs = get_fpu_register_float(fs_reg());
2810 float ft = get_fpu_register_float(ft_reg()); 2811 float ft = get_fpu_register_float(ft_reg());
2811 int32_t alu_out = 0x12345678; 2812 int32_t alu_out = 0x12345678;
2812 switch (get_instr()->FunctionFieldRaw()) { 2813 switch (instr_.FunctionFieldRaw()) {
2813 case CVT_S_W: // Convert word to float (single). 2814 case CVT_S_W: // Convert word to float (single).
2814 alu_out = get_fpu_register_signed_word(fs_reg()); 2815 alu_out = get_fpu_register_signed_word(fs_reg());
2815 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); 2816 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out));
2816 break; 2817 break;
2817 case CVT_D_W: // Convert word to double. 2818 case CVT_D_W: // Convert word to double.
2818 alu_out = get_fpu_register_signed_word(fs_reg()); 2819 alu_out = get_fpu_register_signed_word(fs_reg());
2819 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); 2820 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out));
2820 break; 2821 break;
2821 case CMP_AF: 2822 case CMP_AF:
2822 set_fpu_register_word(fd_reg(), 0); 2823 set_fpu_register_word(fd_reg(), 0);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2898 2899
2899 2900
2900 void Simulator::DecodeTypeRegisterSRsType() { 2901 void Simulator::DecodeTypeRegisterSRsType() {
2901 float fs, ft, fd; 2902 float fs, ft, fd;
2902 fs = get_fpu_register_float(fs_reg()); 2903 fs = get_fpu_register_float(fs_reg());
2903 ft = get_fpu_register_float(ft_reg()); 2904 ft = get_fpu_register_float(ft_reg());
2904 fd = get_fpu_register_float(fd_reg()); 2905 fd = get_fpu_register_float(fd_reg());
2905 int32_t ft_int = bit_cast<int32_t>(ft); 2906 int32_t ft_int = bit_cast<int32_t>(ft);
2906 int32_t fd_int = bit_cast<int32_t>(fd); 2907 int32_t fd_int = bit_cast<int32_t>(fd);
2907 uint32_t cc, fcsr_cc; 2908 uint32_t cc, fcsr_cc;
2908 cc = get_instr()->FCccValue(); 2909 cc = instr_.FCccValue();
2909 fcsr_cc = get_fcsr_condition_bit(cc); 2910 fcsr_cc = get_fcsr_condition_bit(cc);
2910 switch (get_instr()->FunctionFieldRaw()) { 2911 switch (instr_.FunctionFieldRaw()) {
2911 case RINT: { 2912 case RINT: {
2912 DCHECK(IsMipsArchVariant(kMips32r6)); 2913 DCHECK(IsMipsArchVariant(kMips32r6));
2913 float result, temp_result; 2914 float result, temp_result;
2914 double temp; 2915 double temp;
2915 float upper = std::ceil(fs); 2916 float upper = std::ceil(fs);
2916 float lower = std::floor(fs); 2917 float lower = std::floor(fs);
2917 switch (get_fcsr_rounding_mode()) { 2918 switch (get_fcsr_rounding_mode()) {
2918 case kRoundToNearest: 2919 case kRoundToNearest:
2919 if (upper - fs < fs - lower) { 2920 if (upper - fs < fs - lower) {
2920 result = upper; 2921 result = upper;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 if (rt() != 0) { 3128 if (rt() != 0) {
3128 set_fpu_register_float(fd_reg(), fs); 3129 set_fpu_register_float(fd_reg(), fs);
3129 } 3130 }
3130 break; 3131 break;
3131 } 3132 }
3132 case MOVF: { 3133 case MOVF: {
3133 // Same function field for MOVT.D and MOVF.D 3134 // Same function field for MOVT.D and MOVF.D
3134 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 3135 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
3135 ft_cc = get_fcsr_condition_bit(ft_cc); 3136 ft_cc = get_fcsr_condition_bit(ft_cc);
3136 3137
3137 if (get_instr()->Bit(16)) { // Read Tf bit. 3138 if (instr_.Bit(16)) { // Read Tf bit.
3138 // MOVT.D 3139 // MOVT.D
3139 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3140 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
3140 } else { 3141 } else {
3141 // MOVF.D 3142 // MOVF.D
3142 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3143 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
3143 } 3144 }
3144 break; 3145 break;
3145 } 3146 }
3146 case TRUNC_W_S: { // Truncate single to word (round towards 0). 3147 case TRUNC_W_S: { // Truncate single to word (round towards 0).
3147 float rounded = trunc(fs); 3148 float rounded = trunc(fs);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3289 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S 3290 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
3290 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. 3291 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
3291 UNREACHABLE(); 3292 UNREACHABLE();
3292 } 3293 }
3293 } 3294 }
3294 3295
3295 3296
3296 void Simulator::DecodeTypeRegisterLRsType() { 3297 void Simulator::DecodeTypeRegisterLRsType() {
3297 double fs = get_fpu_register_double(fs_reg()); 3298 double fs = get_fpu_register_double(fs_reg());
3298 double ft = get_fpu_register_double(ft_reg()); 3299 double ft = get_fpu_register_double(ft_reg());
3299 switch (get_instr()->FunctionFieldRaw()) { 3300 switch (instr_.FunctionFieldRaw()) {
3300 case CVT_D_L: // Mips32r2 instruction. 3301 case CVT_D_L: // Mips32r2 instruction.
3301 // Watch the signs here, we want 2 32-bit vals 3302 // Watch the signs here, we want 2 32-bit vals
3302 // to make a sign-64. 3303 // to make a sign-64.
3303 int64_t i64; 3304 int64_t i64;
3304 if (IsFp64Mode()) { 3305 if (IsFp64Mode()) {
3305 i64 = get_fpu_register(fs_reg()); 3306 i64 = get_fpu_register(fs_reg());
3306 } else { 3307 } else {
3307 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); 3308 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg()));
3308 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32; 3309 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32;
3309 } 3310 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3391 set_fpu_register(fd_reg(), 0); 3392 set_fpu_register(fd_reg(), 0);
3392 } 3393 }
3393 break; 3394 break;
3394 default: 3395 default:
3395 UNREACHABLE(); 3396 UNREACHABLE();
3396 } 3397 }
3397 } 3398 }
3398 3399
3399 3400
3400 void Simulator::DecodeTypeRegisterCOP1() { 3401 void Simulator::DecodeTypeRegisterCOP1() {
3401 switch (get_instr()->RsFieldRaw()) { 3402 switch (instr_.RsFieldRaw()) {
3402 case CFC1: 3403 case CFC1:
3403 // At the moment only FCSR is supported. 3404 // At the moment only FCSR is supported.
3404 DCHECK(fs_reg() == kFCSRRegister); 3405 DCHECK(fs_reg() == kFCSRRegister);
3405 set_register(rt_reg(), FCSR_); 3406 set_register(rt_reg(), FCSR_);
3406 break; 3407 break;
3407 case MFC1: 3408 case MFC1:
3408 set_register(rt_reg(), get_fpu_register_word(fs_reg())); 3409 set_register(rt_reg(), get_fpu_register_word(fs_reg()));
3409 break; 3410 break;
3410 case MFHC1: 3411 case MFHC1:
3411 if (IsFp64Mode()) { 3412 if (IsFp64Mode()) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3454 case PS: 3455 case PS:
3455 // Not implemented. 3456 // Not implemented.
3456 UNREACHABLE(); 3457 UNREACHABLE();
3457 default: 3458 default:
3458 UNREACHABLE(); 3459 UNREACHABLE();
3459 } 3460 }
3460 } 3461 }
3461 3462
3462 3463
3463 void Simulator::DecodeTypeRegisterCOP1X() { 3464 void Simulator::DecodeTypeRegisterCOP1X() {
3464 switch (get_instr()->FunctionFieldRaw()) { 3465 switch (instr_.FunctionFieldRaw()) {
3465 case MADD_S: { 3466 case MADD_S: {
3466 DCHECK(IsMipsArchVariant(kMips32r2)); 3467 DCHECK(IsMipsArchVariant(kMips32r2));
3467 float fr, ft, fs; 3468 float fr, ft, fs;
3468 fr = get_fpu_register_float(fr_reg()); 3469 fr = get_fpu_register_float(fr_reg());
3469 fs = get_fpu_register_float(fs_reg()); 3470 fs = get_fpu_register_float(fs_reg());
3470 ft = get_fpu_register_float(ft_reg()); 3471 ft = get_fpu_register_float(ft_reg());
3471 set_fpu_register_float(fd_reg(), fs * ft + fr); 3472 set_fpu_register_float(fd_reg(), fs * ft + fr);
3472 break; 3473 break;
3473 } 3474 }
3474 case MSUB_S: { 3475 case MSUB_S: {
(...skipping 28 matching lines...) Expand all
3503 } 3504 }
3504 } 3505 }
3505 3506
3506 3507
3507 void Simulator::DecodeTypeRegisterSPECIAL() { 3508 void Simulator::DecodeTypeRegisterSPECIAL() {
3508 int64_t alu_out = 0x12345678; 3509 int64_t alu_out = 0x12345678;
3509 int64_t i64hilo = 0; 3510 int64_t i64hilo = 0;
3510 uint64_t u64hilo = 0; 3511 uint64_t u64hilo = 0;
3511 bool do_interrupt = false; 3512 bool do_interrupt = false;
3512 3513
3513 switch (get_instr()->FunctionFieldRaw()) { 3514 switch (instr_.FunctionFieldRaw()) {
3514 case SELEQZ_S: 3515 case SELEQZ_S:
3515 DCHECK(IsMipsArchVariant(kMips32r6)); 3516 DCHECK(IsMipsArchVariant(kMips32r6));
3516 set_register(rd_reg(), rt() == 0 ? rs() : 0); 3517 set_register(rd_reg(), rt() == 0 ? rs() : 0);
3517 break; 3518 break;
3518 case SELNEZ_S: 3519 case SELNEZ_S:
3519 DCHECK(IsMipsArchVariant(kMips32r6)); 3520 DCHECK(IsMipsArchVariant(kMips32r6));
3520 set_register(rd_reg(), rt() != 0 ? rs() : 0); 3521 set_register(rd_reg(), rt() != 0 ? rs() : 0);
3521 break; 3522 break;
3522 case JR: { 3523 case JR: {
3523 int32_t next_pc = rs(); 3524 int32_t next_pc = rs();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); 3644 set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32));
3644 break; 3645 break;
3645 default: 3646 default:
3646 UNIMPLEMENTED_MIPS(); 3647 UNIMPLEMENTED_MIPS();
3647 break; 3648 break;
3648 } 3649 }
3649 } 3650 }
3650 break; 3651 break;
3651 case DIV: 3652 case DIV:
3652 if (IsMipsArchVariant(kMips32r6)) { 3653 if (IsMipsArchVariant(kMips32r6)) {
3653 switch (get_instr()->SaValue()) { 3654 switch (sa()) {
3654 case DIV_OP: 3655 case DIV_OP:
3655 if (rs() == INT_MIN && rt() == -1) { 3656 if (rs() == INT_MIN && rt() == -1) {
3656 set_register(rd_reg(), INT_MIN); 3657 set_register(rd_reg(), INT_MIN);
3657 } else if (rt() != 0) { 3658 } else if (rt() != 0) {
3658 set_register(rd_reg(), rs() / rt()); 3659 set_register(rd_reg(), rs() / rt());
3659 } 3660 }
3660 break; 3661 break;
3661 case MOD_OP: 3662 case MOD_OP:
3662 if (rs() == INT_MIN && rt() == -1) { 3663 if (rs() == INT_MIN && rt() == -1) {
3663 set_register(rd_reg(), 0); 3664 set_register(rd_reg(), 0);
(...skipping 14 matching lines...) Expand all
3678 set_register(LO, INT_MIN); 3679 set_register(LO, INT_MIN);
3679 set_register(HI, 0); 3680 set_register(HI, 0);
3680 } else if (rt() != 0) { 3681 } else if (rt() != 0) {
3681 set_register(LO, rs() / rt()); 3682 set_register(LO, rs() / rt());
3682 set_register(HI, rs() % rt()); 3683 set_register(HI, rs() % rt());
3683 } 3684 }
3684 } 3685 }
3685 break; 3686 break;
3686 case DIVU: 3687 case DIVU:
3687 if (IsMipsArchVariant(kMips32r6)) { 3688 if (IsMipsArchVariant(kMips32r6)) {
3688 switch (get_instr()->SaValue()) { 3689 switch (sa()) {
3689 case DIV_OP: 3690 case DIV_OP:
3690 if (rt_u() != 0) { 3691 if (rt_u() != 0) {
3691 set_register(rd_reg(), rs_u() / rt_u()); 3692 set_register(rd_reg(), rs_u() / rt_u());
3692 } 3693 }
3693 break; 3694 break;
3694 case MOD_OP: 3695 case MOD_OP:
3695 if (rt_u() != 0) { 3696 if (rt_u() != 0) {
3696 set_register(rd_reg(), rs_u() % rt_u()); 3697 set_register(rd_reg(), rs_u() % rt_u());
3697 } 3698 }
3698 break; 3699 break;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3785 // TODO(palfia): Ignore sync instruction for now. 3786 // TODO(palfia): Ignore sync instruction for now.
3786 break; 3787 break;
3787 // Conditional moves. 3788 // Conditional moves.
3788 case MOVN: 3789 case MOVN:
3789 if (rt()) { 3790 if (rt()) {
3790 set_register(rd_reg(), rs()); 3791 set_register(rd_reg(), rs());
3791 TraceRegWr(rs()); 3792 TraceRegWr(rs());
3792 } 3793 }
3793 break; 3794 break;
3794 case MOVCI: { 3795 case MOVCI: {
3795 uint32_t cc = get_instr()->FBccValue(); 3796 uint32_t cc = instr_.FBccValue();
3796 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 3797 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
3797 if (get_instr()->Bit(16)) { // Read Tf bit. 3798 if (instr_.Bit(16)) { // Read Tf bit.
3798 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); 3799 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3799 } else { 3800 } else {
3800 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); 3801 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3801 } 3802 }
3802 break; 3803 break;
3803 } 3804 }
3804 case MOVZ: 3805 case MOVZ:
3805 if (!rt()) { 3806 if (!rt()) {
3806 set_register(rd_reg(), rs()); 3807 set_register(rd_reg(), rs());
3807 TraceRegWr(rs()); 3808 TraceRegWr(rs());
3808 } 3809 }
3809 break; 3810 break;
3810 default: 3811 default:
3811 UNREACHABLE(); 3812 UNREACHABLE();
3812 } 3813 }
3813 if (do_interrupt) { 3814 if (do_interrupt) {
3814 SoftwareInterrupt(get_instr()); 3815 SoftwareInterrupt();
3815 } 3816 }
3816 } 3817 }
3817 3818
3818 3819
3819 void Simulator::DecodeTypeRegisterSPECIAL2() { 3820 void Simulator::DecodeTypeRegisterSPECIAL2() {
3820 int32_t alu_out; 3821 int32_t alu_out;
3821 switch (get_instr()->FunctionFieldRaw()) { 3822 switch (instr_.FunctionFieldRaw()) {
3822 case MUL: 3823 case MUL:
3823 // Only the lower 32 bits are kept. 3824 // Only the lower 32 bits are kept.
3824 alu_out = rs_u() * rt_u(); 3825 alu_out = rs_u() * rt_u();
3825 // HI and LO are UNPREDICTABLE after the operation. 3826 // HI and LO are UNPREDICTABLE after the operation.
3826 set_register(LO, Unpredictable); 3827 set_register(LO, Unpredictable);
3827 set_register(HI, Unpredictable); 3828 set_register(HI, Unpredictable);
3828 break; 3829 break;
3829 case CLZ: 3830 case CLZ:
3830 // MIPS32 spec: If no bits were set in GPR rs, the result written to 3831 // MIPS32 spec: If no bits were set in GPR rs, the result written to
3831 // GPR rd is 32. 3832 // GPR rd is 32.
3832 alu_out = base::bits::CountLeadingZeros32(rs_u()); 3833 alu_out = base::bits::CountLeadingZeros32(rs_u());
3833 break; 3834 break;
3834 default: 3835 default:
3835 alu_out = 0x12345678; 3836 alu_out = 0x12345678;
3836 UNREACHABLE(); 3837 UNREACHABLE();
3837 } 3838 }
3838 SetResult(rd_reg(), alu_out); 3839 SetResult(rd_reg(), alu_out);
3839 } 3840 }
3840 3841
3841 3842
3842 void Simulator::DecodeTypeRegisterSPECIAL3() { 3843 void Simulator::DecodeTypeRegisterSPECIAL3() {
3843 int32_t alu_out; 3844 int32_t alu_out;
3844 switch (get_instr()->FunctionFieldRaw()) { 3845 switch (instr_.FunctionFieldRaw()) {
3845 case INS: { // Mips32r2 instruction. 3846 case INS: { // Mips32r2 instruction.
3846 // Interpret rd field as 5-bit msb of insert. 3847 // Interpret rd field as 5-bit msb of insert.
3847 uint16_t msb = rd_reg(); 3848 uint16_t msb = rd_reg();
3848 // Interpret sa field as 5-bit lsb of insert. 3849 // Interpret sa field as 5-bit lsb of insert.
3849 uint16_t lsb = sa(); 3850 uint16_t lsb = sa();
3850 uint16_t size = msb - lsb + 1; 3851 uint16_t size = msb - lsb + 1;
3851 uint32_t mask = (1 << size) - 1; 3852 uint32_t mask = (1 << size) - 1;
3852 alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb); 3853 alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb);
3853 // Ins instr leaves result in Rt, rather than Rd. 3854 // Ins instr leaves result in Rt, rather than Rd.
3854 SetResult(rt_reg(), alu_out); 3855 SetResult(rt_reg(), alu_out);
3855 break; 3856 break;
3856 } 3857 }
3857 case EXT: { // Mips32r2 instruction. 3858 case EXT: { // Mips32r2 instruction.
3858 // Interpret rd field as 5-bit msb of extract. 3859 // Interpret rd field as 5-bit msb of extract.
3859 uint16_t msb = rd_reg(); 3860 uint16_t msb = rd_reg();
3860 // Interpret sa field as 5-bit lsb of extract. 3861 // Interpret sa field as 5-bit lsb of extract.
3861 uint16_t lsb = sa(); 3862 uint16_t lsb = sa();
3862 uint16_t size = msb + 1; 3863 uint16_t size = msb + 1;
3863 uint32_t mask = (1 << size) - 1; 3864 uint32_t mask = (1 << size) - 1;
3864 alu_out = (rs_u() & (mask << lsb)) >> lsb; 3865 alu_out = (rs_u() & (mask << lsb)) >> lsb;
3865 SetResult(rt_reg(), alu_out); 3866 SetResult(rt_reg(), alu_out);
3866 break; 3867 break;
3867 } 3868 }
3868 case BSHFL: { 3869 case BSHFL: {
3869 int sa = get_instr()->SaFieldRaw() >> kSaShift; 3870 int sa = instr_.SaFieldRaw() >> kSaShift;
3870 switch (sa) { 3871 switch (sa) {
3871 case BITSWAP: { 3872 case BITSWAP: {
3872 uint32_t input = static_cast<uint32_t>(rt()); 3873 uint32_t input = static_cast<uint32_t>(rt());
3873 uint32_t output = 0; 3874 uint32_t output = 0;
3874 uint8_t i_byte, o_byte; 3875 uint8_t i_byte, o_byte;
3875 3876
3876 // Reverse the bit in byte for each individual byte 3877 // Reverse the bit in byte for each individual byte
3877 for (int i = 0; i < 4; i++) { 3878 for (int i = 0; i < 4; i++) {
3878 output = output >> 8; 3879 output = output >> 8;
3879 i_byte = input & 0xff; 3880 i_byte = input & 0xff;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3931 tmp = tmp << 8; 3932 tmp = tmp << 8;
3932 } 3933 }
3933 output = output | tmp; 3934 output = output | tmp;
3934 mask = mask >> 8; 3935 mask = mask >> 8;
3935 } 3936 }
3936 3937
3937 alu_out = static_cast<int32_t>(output); 3938 alu_out = static_cast<int32_t>(output);
3938 break; 3939 break;
3939 } 3940 }
3940 default: { 3941 default: {
3941 const uint8_t bp = get_instr()->Bp2Value(); 3942 const uint8_t bp = instr_.Bp2Value();
3942 sa >>= kBp2Bits; 3943 sa >>= kBp2Bits;
3943 switch (sa) { 3944 switch (sa) {
3944 case ALIGN: { 3945 case ALIGN: {
3945 if (bp == 0) { 3946 if (bp == 0) {
3946 alu_out = static_cast<int32_t>(rt()); 3947 alu_out = static_cast<int32_t>(rt());
3947 } else { 3948 } else {
3948 uint32_t rt_hi = rt() << (8 * bp); 3949 uint32_t rt_hi = rt() << (8 * bp);
3949 uint32_t rs_lo = rs() >> (8 * (4 - bp)); 3950 uint32_t rs_lo = rs() >> (8 * (4 - bp));
3950 alu_out = static_cast<int32_t>(rt_hi | rs_lo); 3951 alu_out = static_cast<int32_t>(rt_hi | rs_lo);
3951 } 3952 }
3952 break; 3953 break;
3953 } 3954 }
3954 default: 3955 default:
3955 alu_out = 0x12345678; 3956 alu_out = 0x12345678;
3956 UNREACHABLE(); 3957 UNREACHABLE();
3957 break; 3958 break;
3958 } 3959 }
3959 } 3960 }
3960 } 3961 }
3961 SetResult(rd_reg(), alu_out); 3962 SetResult(rd_reg(), alu_out);
3962 break; 3963 break;
3963 } 3964 }
3964 default: 3965 default:
3965 UNREACHABLE(); 3966 UNREACHABLE();
3966 } 3967 }
3967 } 3968 }
3968 3969
3969 3970 void Simulator::DecodeTypeRegister() {
3970 void Simulator::DecodeTypeRegister(Instruction* instr) {
3971 const Opcode op = instr->OpcodeFieldRaw();
3972
3973 // Set up the variables if needed before executing the instruction.
3974 // ConfigureTypeRegister(instr);
3975 set_instr(instr);
3976
3977 // ---------- Execution. 3971 // ---------- Execution.
3978 switch (op) { 3972 switch (instr_.OpcodeFieldRaw()) {
3979 case COP1: 3973 case COP1:
3980 DecodeTypeRegisterCOP1(); 3974 DecodeTypeRegisterCOP1();
3981 break; 3975 break;
3982 case COP1X: 3976 case COP1X:
3983 DecodeTypeRegisterCOP1X(); 3977 DecodeTypeRegisterCOP1X();
3984 break; 3978 break;
3985 case SPECIAL: 3979 case SPECIAL:
3986 DecodeTypeRegisterSPECIAL(); 3980 DecodeTypeRegisterSPECIAL();
3987 break; 3981 break;
3988 case SPECIAL2: 3982 case SPECIAL2:
3989 DecodeTypeRegisterSPECIAL2(); 3983 DecodeTypeRegisterSPECIAL2();
3990 break; 3984 break;
3991 case SPECIAL3: 3985 case SPECIAL3:
3992 DecodeTypeRegisterSPECIAL3(); 3986 DecodeTypeRegisterSPECIAL3();
3993 break; 3987 break;
3994 default: 3988 default:
3995 UNREACHABLE(); 3989 UNREACHABLE();
3996 } 3990 }
3997 } 3991 }
3998 3992
3999 3993
4000 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). 3994 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc).
4001 void Simulator::DecodeTypeImmediate(Instruction* instr) { 3995 void Simulator::DecodeTypeImmediate() {
4002 // Instruction fields. 3996 // Instruction fields.
4003 Opcode op = instr->OpcodeFieldRaw(); 3997 Opcode op = instr_.OpcodeFieldRaw();
4004 int32_t rs_reg = instr->RsValue(); 3998 int32_t rs_reg = instr_.RsValue();
4005 int32_t rs = get_register(instr->RsValue()); 3999 int32_t rs = get_register(instr_.RsValue());
4006 uint32_t rs_u = static_cast<uint32_t>(rs); 4000 uint32_t rs_u = static_cast<uint32_t>(rs);
4007 int32_t rt_reg = instr->RtValue(); // Destination register. 4001 int32_t rt_reg = instr_.RtValue(); // Destination register.
4008 int32_t rt = get_register(rt_reg); 4002 int32_t rt = get_register(rt_reg);
4009 int16_t imm16 = instr->Imm16Value(); 4003 int16_t imm16 = instr_.Imm16Value();
4010 4004
4011 int32_t ft_reg = instr->FtValue(); // Destination register. 4005 int32_t ft_reg = instr_.FtValue(); // Destination register.
4012 4006
4013 // Zero extended immediate. 4007 // Zero extended immediate.
4014 uint32_t oe_imm16 = 0xffff & imm16; 4008 uint32_t oe_imm16 = 0xffff & imm16;
4015 // Sign extended immediate. 4009 // Sign extended immediate.
4016 int32_t se_imm16 = imm16; 4010 int32_t se_imm16 = imm16;
4017 4011
4018 // Next pc. 4012 // Next pc.
4019 int32_t next_pc = bad_ra; 4013 int32_t next_pc = bad_ra;
4020 4014
4021 // Used for conditional branch instructions. 4015 // Used for conditional branch instructions.
4022 bool execute_branch_delay_instruction = false; 4016 bool execute_branch_delay_instruction = false;
4023 4017
4024 // Used for arithmetic instructions. 4018 // Used for arithmetic instructions.
4025 int32_t alu_out = 0; 4019 int32_t alu_out = 0;
4026 4020
4027 // Used for memory instructions. 4021 // Used for memory instructions.
4028 int32_t addr = 0x0; 4022 int32_t addr = 0x0;
4029 4023
4030 // Branch instructions common part. 4024 // Branch instructions common part.
4031 auto BranchAndLinkHelper = [this, instr, &next_pc, 4025 auto BranchAndLinkHelper =
4032 &execute_branch_delay_instruction]( 4026 [this, &next_pc, &execute_branch_delay_instruction](bool do_branch) {
4033 bool do_branch) { 4027 execute_branch_delay_instruction = true;
4034 execute_branch_delay_instruction = true; 4028 int32_t current_pc = get_pc();
4035 int32_t current_pc = get_pc(); 4029 if (do_branch) {
4036 if (do_branch) { 4030 int16_t imm16 = this->instr_.Imm16Value();
4037 int16_t imm16 = instr->Imm16Value(); 4031 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4038 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 4032 set_register(31, current_pc + 2 * Instruction::kInstrSize);
4039 set_register(31, current_pc + 2 * Instruction::kInstrSize); 4033 } else {
4040 } else { 4034 next_pc = current_pc + 2 * Instruction::kInstrSize;
4041 next_pc = current_pc + 2 * Instruction::kInstrSize; 4035 }
4042 } 4036 };
4043 };
4044 4037
4045 auto BranchHelper = [this, instr, &next_pc, 4038 auto BranchHelper = [this, &next_pc,
4046 &execute_branch_delay_instruction](bool do_branch) { 4039 &execute_branch_delay_instruction](bool do_branch) {
4047 execute_branch_delay_instruction = true; 4040 execute_branch_delay_instruction = true;
4048 int32_t current_pc = get_pc(); 4041 int32_t current_pc = get_pc();
4049 if (do_branch) { 4042 if (do_branch) {
4050 int16_t imm16 = instr->Imm16Value(); 4043 int16_t imm16 = this->instr_.Imm16Value();
4051 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; 4044 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
4052 } else { 4045 } else {
4053 next_pc = current_pc + 2 * Instruction::kInstrSize; 4046 next_pc = current_pc + 2 * Instruction::kInstrSize;
4054 } 4047 }
4055 }; 4048 };
4056 4049
4057 auto BranchAndLinkCompactHelper = [this, instr, &next_pc](bool do_branch, 4050 auto BranchAndLinkCompactHelper = [this, &next_pc](bool do_branch, int bits) {
4058 int bits) {
4059 int32_t current_pc = get_pc(); 4051 int32_t current_pc = get_pc();
4060 CheckForbiddenSlot(current_pc); 4052 CheckForbiddenSlot(current_pc);
4061 if (do_branch) { 4053 if (do_branch) {
4062 int32_t imm = instr->ImmValue(bits); 4054 int32_t imm = this->instr_.ImmValue(bits);
4063 imm <<= 32 - bits; 4055 imm <<= 32 - bits;
4064 imm >>= 32 - bits; 4056 imm >>= 32 - bits;
4065 next_pc = current_pc + (imm << 2) + Instruction::kInstrSize; 4057 next_pc = current_pc + (imm << 2) + Instruction::kInstrSize;
4066 set_register(31, current_pc + Instruction::kInstrSize); 4058 set_register(31, current_pc + Instruction::kInstrSize);
4067 } 4059 }
4068 }; 4060 };
4069 4061
4070 auto BranchCompactHelper = [&next_pc, this, instr](bool do_branch, int bits) { 4062 auto BranchCompactHelper = [this, &next_pc](bool do_branch, int bits) {
4071 int32_t current_pc = get_pc(); 4063 int32_t current_pc = get_pc();
4072 CheckForbiddenSlot(current_pc); 4064 CheckForbiddenSlot(current_pc);
4073 if (do_branch) { 4065 if (do_branch) {
4074 int32_t imm = instr->ImmValue(bits); 4066 int32_t imm = this->instr_.ImmValue(bits);
4075 imm <<= 32 - bits; 4067 imm <<= 32 - bits;
4076 imm >>= 32 - bits; 4068 imm >>= 32 - bits;
4077 next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize; 4069 next_pc = get_pc() + (imm << 2) + Instruction::kInstrSize;
4078 } 4070 }
4079 }; 4071 };
4080 4072
4081
4082 switch (op) { 4073 switch (op) {
4083 // ------------- COP1. Coprocessor instructions. 4074 // ------------- COP1. Coprocessor instructions.
4084 case COP1: 4075 case COP1:
4085 switch (instr->RsFieldRaw()) { 4076 switch (instr_.RsFieldRaw()) {
4086 case BC1: { // Branch on coprocessor condition. 4077 case BC1: { // Branch on coprocessor condition.
4087 // Floating point. 4078 // Floating point.
4088 uint32_t cc = instr->FBccValue(); 4079 uint32_t cc = instr_.FBccValue();
4089 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 4080 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
4090 uint32_t cc_value = test_fcsr_bit(fcsr_cc); 4081 uint32_t cc_value = test_fcsr_bit(fcsr_cc);
4091 bool do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; 4082 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value;
4092 BranchHelper(do_branch); 4083 BranchHelper(do_branch);
4093 break; 4084 break;
4094 } 4085 }
4095 case BC1EQZ: 4086 case BC1EQZ:
4096 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); 4087 BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
4097 break; 4088 break;
4098 case BC1NEZ: 4089 case BC1NEZ:
4099 BranchHelper(get_fpu_register(ft_reg) & 0x1); 4090 BranchHelper(get_fpu_register(ft_reg) & 0x1);
4100 break; 4091 break;
4101 default: 4092 default:
4102 UNREACHABLE(); 4093 UNREACHABLE();
4103 } 4094 }
4104 break; 4095 break;
4105 // ------------- REGIMM class. 4096 // ------------- REGIMM class.
4106 case REGIMM: 4097 case REGIMM:
4107 switch (instr->RtFieldRaw()) { 4098 switch (instr_.RtFieldRaw()) {
4108 case BLTZ: 4099 case BLTZ:
4109 BranchHelper(rs < 0); 4100 BranchHelper(rs < 0);
4110 break; 4101 break;
4111 case BGEZ: 4102 case BGEZ:
4112 BranchHelper(rs >= 0); 4103 BranchHelper(rs >= 0);
4113 break; 4104 break;
4114 case BLTZAL: 4105 case BLTZAL:
4115 BranchAndLinkHelper(rs < 0); 4106 BranchAndLinkHelper(rs < 0);
4116 break; 4107 break;
4117 case BGEZAL: 4108 case BGEZAL:
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
4305 } else { 4296 } else {
4306 // LUI 4297 // LUI
4307 SetResult(rt_reg, oe_imm16 << 16); 4298 SetResult(rt_reg, oe_imm16 << 16);
4308 } 4299 }
4309 break; 4300 break;
4310 // ------------- Memory instructions. 4301 // ------------- Memory instructions.
4311 case LB: 4302 case LB:
4312 set_register(rt_reg, ReadB(rs + se_imm16)); 4303 set_register(rt_reg, ReadB(rs + se_imm16));
4313 break; 4304 break;
4314 case LH: 4305 case LH:
4315 set_register(rt_reg, ReadH(rs + se_imm16, instr)); 4306 set_register(rt_reg, ReadH(rs + se_imm16, instr_.instr()));
4316 break; 4307 break;
4317 case LWL: { 4308 case LWL: {
4318 // al_offset is offset of the effective address within an aligned word. 4309 // al_offset is offset of the effective address within an aligned word.
4319 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 4310 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
4320 uint8_t byte_shift = kPointerAlignmentMask - al_offset; 4311 uint8_t byte_shift = kPointerAlignmentMask - al_offset;
4321 uint32_t mask = (1 << byte_shift * 8) - 1; 4312 uint32_t mask = (1 << byte_shift * 8) - 1;
4322 addr = rs + se_imm16 - al_offset; 4313 addr = rs + se_imm16 - al_offset;
4323 alu_out = ReadW(addr, instr); 4314 alu_out = ReadW(addr, instr_.instr());
4324 alu_out <<= byte_shift * 8; 4315 alu_out <<= byte_shift * 8;
4325 alu_out |= rt & mask; 4316 alu_out |= rt & mask;
4326 set_register(rt_reg, alu_out); 4317 set_register(rt_reg, alu_out);
4327 break; 4318 break;
4328 } 4319 }
4329 case LW: 4320 case LW:
4330 set_register(rt_reg, ReadW(rs + se_imm16, instr)); 4321 set_register(rt_reg, ReadW(rs + se_imm16, instr_.instr()));
4331 break; 4322 break;
4332 case LBU: 4323 case LBU:
4333 set_register(rt_reg, ReadBU(rs + se_imm16)); 4324 set_register(rt_reg, ReadBU(rs + se_imm16));
4334 break; 4325 break;
4335 case LHU: 4326 case LHU:
4336 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); 4327 set_register(rt_reg, ReadHU(rs + se_imm16, instr_.instr()));
4337 break; 4328 break;
4338 case LWR: { 4329 case LWR: {
4339 // al_offset is offset of the effective address within an aligned word. 4330 // al_offset is offset of the effective address within an aligned word.
4340 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 4331 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
4341 uint8_t byte_shift = kPointerAlignmentMask - al_offset; 4332 uint8_t byte_shift = kPointerAlignmentMask - al_offset;
4342 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; 4333 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
4343 addr = rs + se_imm16 - al_offset; 4334 addr = rs + se_imm16 - al_offset;
4344 alu_out = ReadW(addr, instr); 4335 alu_out = ReadW(addr, instr_.instr());
4345 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; 4336 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
4346 alu_out |= rt & mask; 4337 alu_out |= rt & mask;
4347 set_register(rt_reg, alu_out); 4338 set_register(rt_reg, alu_out);
4348 break; 4339 break;
4349 } 4340 }
4350 case SB: 4341 case SB:
4351 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); 4342 WriteB(rs + se_imm16, static_cast<int8_t>(rt));
4352 break; 4343 break;
4353 case SH: 4344 case SH:
4354 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); 4345 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr_.instr());
4355 break; 4346 break;
4356 case SWL: { 4347 case SWL: {
4357 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 4348 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
4358 uint8_t byte_shift = kPointerAlignmentMask - al_offset; 4349 uint8_t byte_shift = kPointerAlignmentMask - al_offset;
4359 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; 4350 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
4360 addr = rs + se_imm16 - al_offset; 4351 addr = rs + se_imm16 - al_offset;
4361 // Value to be written in memory. 4352 // Value to be written in memory.
4362 uint32_t mem_value = ReadW(addr, instr) & mask; 4353 uint32_t mem_value = ReadW(addr, instr_.instr()) & mask;
4363 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8; 4354 mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
4364 WriteW(addr, mem_value, instr); 4355 WriteW(addr, mem_value, instr_.instr());
4365 break; 4356 break;
4366 } 4357 }
4367 case SW: 4358 case SW:
4368 WriteW(rs + se_imm16, rt, instr); 4359 WriteW(rs + se_imm16, rt, instr_.instr());
4369 break; 4360 break;
4370 case SWR: { 4361 case SWR: {
4371 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 4362 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
4372 uint32_t mask = (1 << al_offset * 8) - 1; 4363 uint32_t mask = (1 << al_offset * 8) - 1;
4373 addr = rs + se_imm16 - al_offset; 4364 addr = rs + se_imm16 - al_offset;
4374 uint32_t mem_value = ReadW(addr, instr); 4365 uint32_t mem_value = ReadW(addr, instr_.instr());
4375 mem_value = (rt << al_offset * 8) | (mem_value & mask); 4366 mem_value = (rt << al_offset * 8) | (mem_value & mask);
4376 WriteW(addr, mem_value, instr); 4367 WriteW(addr, mem_value, instr_.instr());
4377 break; 4368 break;
4378 } 4369 }
4379 case LWC1: 4370 case LWC1:
4380 set_fpu_register_hi_word(ft_reg, 0); 4371 set_fpu_register_hi_word(ft_reg, 0);
4381 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); 4372 set_fpu_register_word(ft_reg,
4373 ReadW(rs + se_imm16, instr_.instr()));
4382 break; 4374 break;
4383 case LDC1: 4375 case LDC1:
4384 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); 4376 set_fpu_register_double(ft_reg,
4377 ReadD(rs + se_imm16, instr_.instr()));
4385 break; 4378 break;
4386 case SWC1: 4379 case SWC1:
4387 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr); 4380 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg),
4381 instr_.instr());
4388 break; 4382 break;
4389 case SDC1: 4383 case SDC1:
4390 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr); 4384 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg),
4385 instr_.instr());
4391 break; 4386 break;
4392 // ------------- PC-Relative instructions. 4387 // ------------- PC-Relative instructions.
4393 case PCREL: { 4388 case PCREL: {
4394 // rt field: checking 5-bits. 4389 // rt field: checking 5-bits.
4395 int32_t imm21 = instr->Imm21Value(); 4390 int32_t imm21 = instr_.Imm21Value();
4396 int32_t current_pc = get_pc(); 4391 int32_t current_pc = get_pc();
4397 uint8_t rt = (imm21 >> kImm16Bits); 4392 uint8_t rt = (imm21 >> kImm16Bits);
4398 switch (rt) { 4393 switch (rt) {
4399 case ALUIPC: 4394 case ALUIPC:
4400 addr = current_pc + (se_imm16 << 16); 4395 addr = current_pc + (se_imm16 << 16);
4401 alu_out = static_cast<int64_t>(~0x0FFFF) & addr; 4396 alu_out = static_cast<int64_t>(~0x0FFFF) & addr;
4402 break; 4397 break;
4403 case AUIPC: 4398 case AUIPC:
4404 alu_out = current_pc + (se_imm16 << 16); 4399 alu_out = current_pc + (se_imm16 << 16);
4405 break; 4400 break;
4406 default: { 4401 default: {
4407 int32_t imm19 = instr->Imm19Value(); 4402 int32_t imm19 = instr_.Imm19Value();
4408 // rt field: checking the most significant 2-bits. 4403 // rt field: checking the most significant 2-bits.
4409 rt = (imm21 >> kImm19Bits); 4404 rt = (imm21 >> kImm19Bits);
4410 switch (rt) { 4405 switch (rt) {
4411 case LWPC: { 4406 case LWPC: {
4412 // Set sign. 4407 // Set sign.
4413 imm19 <<= (kOpcodeBits + kRsBits + 2); 4408 imm19 <<= (kOpcodeBits + kRsBits + 2);
4414 imm19 >>= (kOpcodeBits + kRsBits + 2); 4409 imm19 >>= (kOpcodeBits + kRsBits + 2);
4415 addr = current_pc + (imm19 << 2); 4410 addr = current_pc + (imm19 << 2);
4416 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 4411 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
4417 alu_out = *ptr; 4412 alu_out = *ptr;
(...skipping 27 matching lines...) Expand all
4445 } 4440 }
4446 4441
4447 // If needed update pc after the branch delay execution. 4442 // If needed update pc after the branch delay execution.
4448 if (next_pc != bad_ra) { 4443 if (next_pc != bad_ra) {
4449 set_pc(next_pc); 4444 set_pc(next_pc);
4450 } 4445 }
4451 } 4446 }
4452 4447
4453 4448
4454 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal). 4449 // Type 3: instructions using a 26 bytes immediate. (e.g. j, jal).
4455 void Simulator::DecodeTypeJump(Instruction* instr) { 4450 void Simulator::DecodeTypeJump() {
4451 SimInstruction simInstr = instr_;
4456 // Get current pc. 4452 // Get current pc.
4457 int32_t current_pc = get_pc(); 4453 int32_t current_pc = get_pc();
4458 // Get unchanged bits of pc. 4454 // Get unchanged bits of pc.
4459 int32_t pc_high_bits = current_pc & 0xf0000000; 4455 int32_t pc_high_bits = current_pc & 0xf0000000;
4460 // Next pc. 4456 // Next pc.
4461 int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2); 4457
4458 int32_t next_pc = pc_high_bits | (simInstr.Imm26Value() << 2);
4462 4459
4463 // Execute branch delay slot. 4460 // Execute branch delay slot.
4464 // We don't check for end_sim_pc. First it should not be met as the current pc 4461 // We don't check for end_sim_pc. First it should not be met as the current pc
4465 // is valid. Secondly a jump should always execute its branch delay slot. 4462 // is valid. Secondly a jump should always execute its branch delay slot.
4466 Instruction* branch_delay_instr = 4463 Instruction* branch_delay_instr =
4467 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); 4464 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
4468 BranchDelayInstructionDecode(branch_delay_instr); 4465 BranchDelayInstructionDecode(branch_delay_instr);
4469 4466
4470 // Update pc and ra if necessary. 4467 // Update pc and ra if necessary.
4471 // Do this after the branch delay execution. 4468 // Do this after the branch delay execution.
4472 if (instr->IsLinkingInstruction()) { 4469 if (simInstr.IsLinkingInstruction()) {
4473 set_register(31, current_pc + 2 * Instruction::kInstrSize); 4470 set_register(31, current_pc + 2 * Instruction::kInstrSize);
4474 } 4471 }
4475 set_pc(next_pc); 4472 set_pc(next_pc);
4476 pc_modified_ = true; 4473 pc_modified_ = true;
4477 } 4474 }
4478 4475
4479 4476
4480 // Executes the current instruction. 4477 // Executes the current instruction.
4481 void Simulator::InstructionDecode(Instruction* instr) { 4478 void Simulator::InstructionDecode(Instruction* instr) {
4482 if (v8::internal::FLAG_check_icache) { 4479 if (v8::internal::FLAG_check_icache) {
4483 CheckICache(isolate_->simulator_i_cache(), instr); 4480 CheckICache(isolate_->simulator_i_cache(), instr);
4484 } 4481 }
4485 pc_modified_ = false; 4482 pc_modified_ = false;
4486 v8::internal::EmbeddedVector<char, 256> buffer; 4483 v8::internal::EmbeddedVector<char, 256> buffer;
4487 if (::v8::internal::FLAG_trace_sim) { 4484 if (::v8::internal::FLAG_trace_sim) {
4488 SNPrintF(trace_buf_, "%s", ""); 4485 SNPrintF(trace_buf_, "%s", "");
4489 disasm::NameConverter converter; 4486 disasm::NameConverter converter;
4490 disasm::Disassembler dasm(converter); 4487 disasm::Disassembler dasm(converter);
4491 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); 4488 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
4492 } 4489 }
4493 4490
4494 switch (instr->InstructionType(Instruction::TypeChecks::EXTRA)) { 4491 instr_ = instr;
4492 switch (instr_.InstructionType()) {
4495 case Instruction::kRegisterType: 4493 case Instruction::kRegisterType:
4496 DecodeTypeRegister(instr); 4494 DecodeTypeRegister();
4497 break; 4495 break;
4498 case Instruction::kImmediateType: 4496 case Instruction::kImmediateType:
4499 DecodeTypeImmediate(instr); 4497 DecodeTypeImmediate();
4500 break; 4498 break;
4501 case Instruction::kJumpType: 4499 case Instruction::kJumpType:
4502 DecodeTypeJump(instr); 4500 DecodeTypeJump();
4503 break; 4501 break;
4504 default: 4502 default:
4505 UNSUPPORTED(); 4503 UNSUPPORTED();
4506 } 4504 }
4507 if (::v8::internal::FLAG_trace_sim) { 4505 if (::v8::internal::FLAG_trace_sim) {
4508 PrintF(" 0x%08" PRIxPTR " %-44s %s\n", 4506 PrintF(" 0x%08" PRIxPTR " %-44s %s\n",
4509 reinterpret_cast<intptr_t>(instr), buffer.start(), 4507 reinterpret_cast<intptr_t>(instr), buffer.start(),
4510 trace_buf_.start()); 4508 trace_buf_.start());
4511 } 4509 }
4512 if (!pc_modified_) { 4510 if (!pc_modified_) {
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
4697 4695
4698 4696
4699 #undef UNSUPPORTED 4697 #undef UNSUPPORTED
4700 4698
4701 } // namespace internal 4699 } // namespace internal
4702 } // namespace v8 4700 } // namespace v8
4703 4701
4704 #endif // USE_SIMULATOR 4702 #endif // USE_SIMULATOR
4705 4703
4706 #endif // V8_TARGET_ARCH_MIPS 4704 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« src/mips/simulator-mips.h ('K') | « src/mips/simulator-mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698