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

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

Powered by Google App Engine
This is Rietveld 408576698