| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "src/v8.h" | 10 #include "src/v8.h" |
| (...skipping 1937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 const int64_t rd_reg = instr->RdValue(); | 1948 const int64_t rd_reg = instr->RdValue(); |
| 1949 const uint64_t sa = instr->SaValue(); | 1949 const uint64_t sa = instr->SaValue(); |
| 1950 | 1950 |
| 1951 const int32_t fs_reg = instr->FsValue(); | 1951 const int32_t fs_reg = instr->FsValue(); |
| 1952 | 1952 |
| 1953 | 1953 |
| 1954 // ---------- Configuration. | 1954 // ---------- Configuration. |
| 1955 switch (op) { | 1955 switch (op) { |
| 1956 case COP1: // Coprocessor instructions. | 1956 case COP1: // Coprocessor instructions. |
| 1957 switch (instr->RsFieldRaw()) { | 1957 switch (instr->RsFieldRaw()) { |
| 1958 case BC1: // Handled in DecodeTypeImmed, should never come here. | |
| 1959 UNREACHABLE(); | |
| 1960 break; | |
| 1961 case CFC1: | 1958 case CFC1: |
| 1962 // At the moment only FCSR is supported. | 1959 // At the moment only FCSR is supported. |
| 1963 ASSERT(fs_reg == kFCSRRegister); | 1960 ASSERT(fs_reg == kFCSRRegister); |
| 1964 *alu_out = FCSR_; | 1961 *alu_out = FCSR_; |
| 1965 break; | 1962 break; |
| 1966 case MFC1: | 1963 case MFC1: |
| 1967 *alu_out = static_cast<int64_t>(get_fpu_register_word(fs_reg)); | 1964 *alu_out = static_cast<int64_t>(get_fpu_register_word(fs_reg)); |
| 1968 break; | 1965 break; |
| 1969 case DMFC1: | 1966 case DMFC1: |
| 1970 *alu_out = get_fpu_register(fs_reg); | 1967 *alu_out = get_fpu_register(fs_reg); |
| 1971 break; | 1968 break; |
| 1972 case MFHC1: | 1969 case MFHC1: |
| 1973 *alu_out = get_fpu_register_hi_word(fs_reg); | 1970 *alu_out = get_fpu_register_hi_word(fs_reg); |
| 1974 break; | 1971 break; |
| 1975 case CTC1: | 1972 case CTC1: |
| 1976 case MTC1: | 1973 case MTC1: |
| 1977 case DMTC1: | 1974 case DMTC1: |
| 1978 case MTHC1: | 1975 case MTHC1: |
| 1979 // Do the store in the execution step. | |
| 1980 break; | |
| 1981 case S: | 1976 case S: |
| 1982 case D: | 1977 case D: |
| 1983 case W: | 1978 case W: |
| 1984 case L: | 1979 case L: |
| 1985 case PS: | 1980 case PS: |
| 1986 // Do everything in the execution step. | 1981 // Do everything in the execution step. |
| 1987 break; | 1982 break; |
| 1988 default: | 1983 default: |
| 1989 UNIMPLEMENTED_MIPS(); | 1984 // BC1 BC1EQZ BC1NEZ handled in DecodeTypeImmed, should never come here. |
| 1985 UNREACHABLE(); |
| 1990 } | 1986 } |
| 1991 break; | 1987 break; |
| 1992 case COP1X: | 1988 case COP1X: |
| 1993 break; | 1989 break; |
| 1994 case SPECIAL: | 1990 case SPECIAL: |
| 1995 switch (instr->FunctionFieldRaw()) { | 1991 switch (instr->FunctionFieldRaw()) { |
| 1996 case JR: | 1992 case JR: |
| 1997 case JALR: | 1993 case JALR: |
| 1998 *next_pc = get_register(instr->RsValue()); | 1994 *next_pc = get_register(instr->RsValue()); |
| 1999 *return_addr_reg = instr->RdValue(); | 1995 *return_addr_reg = instr->RdValue(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 // Release 2. SA field is equal to 00001. | 2060 // Release 2. SA field is equal to 00001. |
| 2065 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u)); | 2061 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u)); |
| 2066 } | 2062 } |
| 2067 break; | 2063 break; |
| 2068 case SRAV: | 2064 case SRAV: |
| 2069 *alu_out = (int32_t)rt >> rs; | 2065 *alu_out = (int32_t)rt >> rs; |
| 2070 break; | 2066 break; |
| 2071 case DSRAV: | 2067 case DSRAV: |
| 2072 *alu_out = rt >> rs; | 2068 *alu_out = rt >> rs; |
| 2073 break; | 2069 break; |
| 2074 case MFHI: | 2070 case MFHI: // MFHI == CLZ on R6. |
| 2075 *alu_out = get_register(HI); | 2071 if (kArchVariant != kMips64r6) { |
| 2072 ASSERT(instr->SaValue() == 0); |
| 2073 *alu_out = get_register(HI); |
| 2074 } else { |
| 2075 // MIPS spec: If no bits were set in GPR rs, the result written to |
| 2076 // GPR rd is 32. |
| 2077 // GCC __builtin_clz: If input is 0, the result is undefined. |
| 2078 ASSERT(instr->SaValue() == 1); |
| 2079 *alu_out = |
| 2080 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); |
| 2081 } |
| 2076 break; | 2082 break; |
| 2077 case MFLO: | 2083 case MFLO: |
| 2078 *alu_out = get_register(LO); | 2084 *alu_out = get_register(LO); |
| 2079 break; | 2085 break; |
| 2080 case MULT: | 2086 case MULT: // MULT == D_MUL_MUH. |
| 2081 // TODO(plind) - Unify MULT/DMULT with single set of 64-bit HI/Lo | 2087 // TODO(plind) - Unify MULT/DMULT with single set of 64-bit HI/Lo |
| 2082 // regs. | 2088 // regs. |
| 2083 // TODO(plind) - make the 32-bit MULT ops conform to spec regarding | 2089 // TODO(plind) - make the 32-bit MULT ops conform to spec regarding |
| 2084 // checking of 32-bit input values, and un-define operations of HW. | 2090 // checking of 32-bit input values, and un-define operations of HW. |
| 2085 *i64hilo = static_cast<int64_t>((int32_t)rs) * | 2091 *i64hilo = static_cast<int64_t>((int32_t)rs) * |
| 2086 static_cast<int64_t>((int32_t)rt); | 2092 static_cast<int64_t>((int32_t)rt); |
| 2087 break; | 2093 break; |
| 2088 case MULTU: | 2094 case MULTU: |
| 2089 *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u); | 2095 *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u); |
| 2090 break; | 2096 break; |
| 2091 case DMULT: | 2097 case DMULT: // DMULT == D_MUL_MUH. |
| 2092 *i128resultH = MultiplyHighSigned(rs, rt); | 2098 if (kArchVariant != kMips64r6) { |
| 2093 *i128resultL = rs * rt; | 2099 *i128resultH = MultiplyHighSigned(rs, rt); |
| 2100 *i128resultL = rs * rt; |
| 2101 } else { |
| 2102 switch (instr->SaValue()) { |
| 2103 case MUL_OP: |
| 2104 *i128resultL = rs * rt; |
| 2105 break; |
| 2106 case MUH_OP: |
| 2107 *i128resultH = MultiplyHighSigned(rs, rt); |
| 2108 break; |
| 2109 default: |
| 2110 UNIMPLEMENTED_MIPS(); |
| 2111 break; |
| 2112 } |
| 2113 } |
| 2094 break; | 2114 break; |
| 2095 case DMULTU: | 2115 case DMULTU: |
| 2096 UNIMPLEMENTED_MIPS(); | 2116 UNIMPLEMENTED_MIPS(); |
| 2097 break; | 2117 break; |
| 2098 case ADD: | 2118 case ADD: |
| 2099 case DADD: | 2119 case DADD: |
| 2100 if (HaveSameSign(rs, rt)) { | 2120 if (HaveSameSign(rs, rt)) { |
| 2101 if (rs > 0) { | 2121 if (rs > 0) { |
| 2102 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); | 2122 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); |
| 2103 } else if (rs < 0) { | 2123 } else if (rs < 0) { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2288 &i128resultL); | 2308 &i128resultL); |
| 2289 | 2309 |
| 2290 // ---------- Raise exceptions triggered. | 2310 // ---------- Raise exceptions triggered. |
| 2291 SignalExceptions(); | 2311 SignalExceptions(); |
| 2292 | 2312 |
| 2293 // ---------- Execution. | 2313 // ---------- Execution. |
| 2294 switch (op) { | 2314 switch (op) { |
| 2295 case COP1: | 2315 case COP1: |
| 2296 switch (instr->RsFieldRaw()) { | 2316 switch (instr->RsFieldRaw()) { |
| 2297 case BC1: // Branch on coprocessor condition. | 2317 case BC1: // Branch on coprocessor condition. |
| 2318 case BC1EQZ: |
| 2319 case BC1NEZ: |
| 2298 UNREACHABLE(); | 2320 UNREACHABLE(); |
| 2299 break; | 2321 break; |
| 2300 case CFC1: | 2322 case CFC1: |
| 2301 set_register(rt_reg, alu_out); | 2323 set_register(rt_reg, alu_out); |
| 2302 break; | 2324 break; |
| 2303 case MFC1: | 2325 case MFC1: |
| 2304 case DMFC1: | 2326 case DMFC1: |
| 2305 case MFHC1: | 2327 case MFHC1: |
| 2306 set_register(rt_reg, alu_out); | 2328 set_register(rt_reg, alu_out); |
| 2307 break; | 2329 break; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2321 case MTHC1: | 2343 case MTHC1: |
| 2322 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]); | 2344 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]); |
| 2323 break; | 2345 break; |
| 2324 case S: | 2346 case S: |
| 2325 float f; | 2347 float f; |
| 2326 switch (instr->FunctionFieldRaw()) { | 2348 switch (instr->FunctionFieldRaw()) { |
| 2327 case CVT_D_S: | 2349 case CVT_D_S: |
| 2328 f = get_fpu_register_float(fs_reg); | 2350 f = get_fpu_register_float(fs_reg); |
| 2329 set_fpu_register_double(fd_reg, static_cast<double>(f)); | 2351 set_fpu_register_double(fd_reg, static_cast<double>(f)); |
| 2330 break; | 2352 break; |
| 2331 case CVT_W_S: | |
| 2332 case CVT_L_S: | |
| 2333 case TRUNC_W_S: | |
| 2334 case TRUNC_L_S: | |
| 2335 case ROUND_W_S: | |
| 2336 case ROUND_L_S: | |
| 2337 case FLOOR_W_S: | |
| 2338 case FLOOR_L_S: | |
| 2339 case CEIL_W_S: | |
| 2340 case CEIL_L_S: | |
| 2341 case CVT_PS_S: | |
| 2342 UNIMPLEMENTED_MIPS(); | |
| 2343 break; | |
| 2344 default: | 2353 default: |
| 2354 // CVT_W_S CVT_L_S TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S |
| 2355 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
| 2345 UNREACHABLE(); | 2356 UNREACHABLE(); |
| 2346 } | 2357 } |
| 2347 break; | 2358 break; |
| 2348 case D: | 2359 case D: |
| 2349 double ft, fs; | 2360 double ft, fs; |
| 2350 uint32_t cc, fcsr_cc; | 2361 uint32_t cc, fcsr_cc; |
| 2351 int64_t i64; | 2362 int64_t i64; |
| 2352 fs = get_fpu_register_double(fs_reg); | 2363 fs = get_fpu_register_double(fs_reg); |
| 2353 ft = get_fpu_register_double(ft_reg); | 2364 ft = get_fpu_register_double(ft_reg); |
| 2354 cc = instr->FCccValue(); | 2365 cc = instr->FCccValue(); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2507 case W: | 2518 case W: |
| 2508 switch (instr->FunctionFieldRaw()) { | 2519 switch (instr->FunctionFieldRaw()) { |
| 2509 case CVT_S_W: // Convert word to float (single). | 2520 case CVT_S_W: // Convert word to float (single). |
| 2510 alu_out = get_fpu_register_signed_word(fs_reg); | 2521 alu_out = get_fpu_register_signed_word(fs_reg); |
| 2511 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); | 2522 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); |
| 2512 break; | 2523 break; |
| 2513 case CVT_D_W: // Convert word to double. | 2524 case CVT_D_W: // Convert word to double. |
| 2514 alu_out = get_fpu_register_signed_word(fs_reg); | 2525 alu_out = get_fpu_register_signed_word(fs_reg); |
| 2515 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); | 2526 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); |
| 2516 break; | 2527 break; |
| 2517 default: | 2528 default: // Mips64r6 CMP.S instructions unimplemented. |
| 2518 UNREACHABLE(); | 2529 UNREACHABLE(); |
| 2519 } | 2530 } |
| 2520 break; | 2531 break; |
| 2521 case L: | 2532 case L: |
| 2533 fs = get_fpu_register_double(fs_reg); |
| 2534 ft = get_fpu_register_double(ft_reg); |
| 2522 switch (instr->FunctionFieldRaw()) { | 2535 switch (instr->FunctionFieldRaw()) { |
| 2523 case CVT_D_L: // Mips32r2 instruction. | 2536 case CVT_D_L: // Mips32r2 instruction. |
| 2524 i64 = get_fpu_register(fs_reg); | 2537 i64 = get_fpu_register(fs_reg); |
| 2525 set_fpu_register_double(fd_reg, static_cast<double>(i64)); | 2538 set_fpu_register_double(fd_reg, static_cast<double>(i64)); |
| 2526 break; | 2539 break; |
| 2527 case CVT_S_L: | 2540 case CVT_S_L: |
| 2528 UNIMPLEMENTED_MIPS(); | 2541 UNIMPLEMENTED_MIPS(); |
| 2529 break; | 2542 break; |
| 2530 default: | 2543 case CMP_AF: // Mips64r6 CMP.D instructions. |
| 2544 UNIMPLEMENTED_MIPS(); |
| 2545 break; |
| 2546 case CMP_UN: |
| 2547 if (std::isnan(fs) || std::isnan(ft)) { |
| 2548 set_fpu_register(fd_reg, -1); |
| 2549 } else { |
| 2550 set_fpu_register(fd_reg, 0); |
| 2551 } |
| 2552 break; |
| 2553 case CMP_EQ: |
| 2554 if (fs == ft) { |
| 2555 set_fpu_register(fd_reg, -1); |
| 2556 } else { |
| 2557 set_fpu_register(fd_reg, 0); |
| 2558 } |
| 2559 break; |
| 2560 case CMP_UEQ: |
| 2561 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2562 set_fpu_register(fd_reg, -1); |
| 2563 } else { |
| 2564 set_fpu_register(fd_reg, 0); |
| 2565 } |
| 2566 break; |
| 2567 case CMP_LT: |
| 2568 if (fs < ft) { |
| 2569 set_fpu_register(fd_reg, -1); |
| 2570 } else { |
| 2571 set_fpu_register(fd_reg, 0); |
| 2572 } |
| 2573 break; |
| 2574 case CMP_ULT: |
| 2575 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2576 set_fpu_register(fd_reg, -1); |
| 2577 } else { |
| 2578 set_fpu_register(fd_reg, 0); |
| 2579 } |
| 2580 break; |
| 2581 case CMP_LE: |
| 2582 if (fs <= ft) { |
| 2583 set_fpu_register(fd_reg, -1); |
| 2584 } else { |
| 2585 set_fpu_register(fd_reg, 0); |
| 2586 } |
| 2587 break; |
| 2588 case CMP_ULE: |
| 2589 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2590 set_fpu_register(fd_reg, -1); |
| 2591 } else { |
| 2592 set_fpu_register(fd_reg, 0); |
| 2593 } |
| 2594 break; |
| 2595 default: // CMP_OR CMP_UNE CMP_NE UNIMPLEMENTED |
| 2531 UNREACHABLE(); | 2596 UNREACHABLE(); |
| 2532 } | 2597 } |
| 2533 break; | 2598 break; |
| 2534 case PS: | |
| 2535 break; | |
| 2536 default: | 2599 default: |
| 2537 UNREACHABLE(); | 2600 UNREACHABLE(); |
| 2538 } | 2601 } |
| 2539 break; | 2602 break; |
| 2540 case COP1X: | 2603 case COP1X: |
| 2541 switch (instr->FunctionFieldRaw()) { | 2604 switch (instr->FunctionFieldRaw()) { |
| 2542 case MADD_D: | 2605 case MADD_D: |
| 2543 double fr, ft, fs; | 2606 double fr, ft, fs; |
| 2544 fr = get_fpu_register_double(fr_reg); | 2607 fr = get_fpu_register_double(fr_reg); |
| 2545 fs = get_fpu_register_double(fs_reg); | 2608 fs = get_fpu_register_double(fs_reg); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2565 current_pc+Instruction::kInstrSize); | 2628 current_pc+Instruction::kInstrSize); |
| 2566 BranchDelayInstructionDecode(branch_delay_instr); | 2629 BranchDelayInstructionDecode(branch_delay_instr); |
| 2567 set_register(return_addr_reg, | 2630 set_register(return_addr_reg, |
| 2568 current_pc + 2 * Instruction::kInstrSize); | 2631 current_pc + 2 * Instruction::kInstrSize); |
| 2569 set_pc(next_pc); | 2632 set_pc(next_pc); |
| 2570 pc_modified_ = true; | 2633 pc_modified_ = true; |
| 2571 break; | 2634 break; |
| 2572 } | 2635 } |
| 2573 // Instructions using HI and LO registers. | 2636 // Instructions using HI and LO registers. |
| 2574 case MULT: | 2637 case MULT: |
| 2575 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); | 2638 if (kArchVariant != kMips64r6) { |
| 2576 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); | 2639 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); |
| 2640 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); |
| 2641 } else { |
| 2642 switch (instr->SaValue()) { |
| 2643 case MUL_OP: |
| 2644 set_register(rd_reg, |
| 2645 static_cast<int32_t>(i64hilo & 0xffffffff)); |
| 2646 break; |
| 2647 case MUH_OP: |
| 2648 set_register(rd_reg, static_cast<int32_t>(i64hilo >> 32)); |
| 2649 break; |
| 2650 default: |
| 2651 UNIMPLEMENTED_MIPS(); |
| 2652 break; |
| 2653 } |
| 2654 } |
| 2577 break; | 2655 break; |
| 2578 case MULTU: | 2656 case MULTU: |
| 2579 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); | 2657 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); |
| 2580 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); | 2658 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); |
| 2581 break; | 2659 break; |
| 2582 case DMULT: | 2660 case DMULT: // DMULT == D_MUL_MUH. |
| 2583 set_register(LO, static_cast<int64_t>(i128resultL)); | 2661 if (kArchVariant != kMips64r6) { |
| 2584 set_register(HI, static_cast<int64_t>(i128resultH)); | 2662 set_register(LO, static_cast<int64_t>(i128resultL)); |
| 2663 set_register(HI, static_cast<int64_t>(i128resultH)); |
| 2664 } else { |
| 2665 switch (instr->SaValue()) { |
| 2666 case MUL_OP: |
| 2667 set_register(rd_reg, static_cast<int64_t>(i128resultL)); |
| 2668 break; |
| 2669 case MUH_OP: |
| 2670 set_register(rd_reg, static_cast<int64_t>(i128resultH)); |
| 2671 break; |
| 2672 default: |
| 2673 UNIMPLEMENTED_MIPS(); |
| 2674 break; |
| 2675 } |
| 2676 } |
| 2585 break; | 2677 break; |
| 2586 case DMULTU: | 2678 case DMULTU: |
| 2587 UNIMPLEMENTED_MIPS(); | 2679 UNIMPLEMENTED_MIPS(); |
| 2588 break; | 2680 break; |
| 2681 case DSLL: |
| 2682 set_register(rd_reg, alu_out); |
| 2683 break; |
| 2589 case DIV: | 2684 case DIV: |
| 2590 case DDIV: | 2685 case DDIV: |
| 2591 // Divide by zero and overflow was not checked in the configuration | 2686 switch (kArchVariant) { |
| 2592 // step - div and divu do not raise exceptions. On division by 0 | 2687 case kMips64r2: |
| 2593 // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1), | 2688 // Divide by zero and overflow was not checked in the |
| 2594 // return INT_MIN which is what the hardware does. | 2689 // configuration step - div and divu do not raise exceptions. On |
| 2595 if (rs == INT_MIN && rt == -1) { | 2690 // division by 0 the result will be UNPREDICTABLE. On overflow |
| 2596 set_register(LO, INT_MIN); | 2691 // (INT_MIN/-1), return INT_MIN which is what the hardware does. |
| 2597 set_register(HI, 0); | 2692 if (rs == INT_MIN && rt == -1) { |
| 2598 } else if (rt != 0) { | 2693 set_register(LO, INT_MIN); |
| 2599 set_register(LO, rs / rt); | 2694 set_register(HI, 0); |
| 2600 set_register(HI, rs % rt); | 2695 } else if (rt != 0) { |
| 2696 set_register(LO, rs / rt); |
| 2697 set_register(HI, rs % rt); |
| 2698 } |
| 2699 break; |
| 2700 case kMips64r6: |
| 2701 switch (instr->SaValue()) { |
| 2702 case DIV_OP: |
| 2703 if (rs == INT_MIN && rt == -1) { |
| 2704 set_register(rd_reg, INT_MIN); |
| 2705 } else if (rt != 0) { |
| 2706 set_register(rd_reg, rs / rt); |
| 2707 } |
| 2708 break; |
| 2709 case MOD_OP: |
| 2710 if (rs == INT_MIN && rt == -1) { |
| 2711 set_register(rd_reg, 0); |
| 2712 } else if (rt != 0) { |
| 2713 set_register(rd_reg, rs % rt); |
| 2714 } |
| 2715 break; |
| 2716 default: |
| 2717 UNIMPLEMENTED_MIPS(); |
| 2718 break; |
| 2719 } |
| 2720 break; |
| 2721 default: |
| 2722 break; |
| 2601 } | 2723 } |
| 2602 break; | 2724 break; |
| 2603 case DIVU: | 2725 case DIVU: |
| 2604 if (rt_u != 0) { | 2726 if (rt_u != 0) { |
| 2605 set_register(LO, rs_u / rt_u); | 2727 set_register(LO, rs_u / rt_u); |
| 2606 set_register(HI, rs_u % rt_u); | 2728 set_register(HI, rs_u % rt_u); |
| 2607 } | 2729 } |
| 2608 break; | 2730 break; |
| 2609 // Break and trap instructions. | 2731 // Break and trap instructions. |
| 2610 case BREAK: | 2732 case BREAK: |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2689 void Simulator::DecodeTypeImmediate(Instruction* instr) { | 2811 void Simulator::DecodeTypeImmediate(Instruction* instr) { |
| 2690 // Instruction fields. | 2812 // Instruction fields. |
| 2691 Opcode op = instr->OpcodeFieldRaw(); | 2813 Opcode op = instr->OpcodeFieldRaw(); |
| 2692 int64_t rs = get_register(instr->RsValue()); | 2814 int64_t rs = get_register(instr->RsValue()); |
| 2693 uint64_t rs_u = static_cast<uint64_t>(rs); | 2815 uint64_t rs_u = static_cast<uint64_t>(rs); |
| 2694 int64_t rt_reg = instr->RtValue(); // Destination register. | 2816 int64_t rt_reg = instr->RtValue(); // Destination register. |
| 2695 int64_t rt = get_register(rt_reg); | 2817 int64_t rt = get_register(rt_reg); |
| 2696 int16_t imm16 = instr->Imm16Value(); | 2818 int16_t imm16 = instr->Imm16Value(); |
| 2697 | 2819 |
| 2698 int32_t ft_reg = instr->FtValue(); // Destination register. | 2820 int32_t ft_reg = instr->FtValue(); // Destination register. |
| 2821 int64_t ft = get_fpu_register(ft_reg); |
| 2699 | 2822 |
| 2700 // Zero extended immediate. | 2823 // Zero extended immediate. |
| 2701 uint32_t oe_imm16 = 0xffff & imm16; | 2824 uint32_t oe_imm16 = 0xffff & imm16; |
| 2702 // Sign extended immediate. | 2825 // Sign extended immediate. |
| 2703 int32_t se_imm16 = imm16; | 2826 int32_t se_imm16 = imm16; |
| 2704 | 2827 |
| 2705 // Get current pc. | 2828 // Get current pc. |
| 2706 int64_t current_pc = get_pc(); | 2829 int64_t current_pc = get_pc(); |
| 2707 // Next pc. | 2830 // Next pc. |
| 2708 int64_t next_pc = bad_ra; | 2831 int64_t next_pc = bad_ra; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2735 cc_value = test_fcsr_bit(fcsr_cc); | 2858 cc_value = test_fcsr_bit(fcsr_cc); |
| 2736 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; | 2859 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; |
| 2737 execute_branch_delay_instruction = true; | 2860 execute_branch_delay_instruction = true; |
| 2738 // Set next_pc. | 2861 // Set next_pc. |
| 2739 if (do_branch) { | 2862 if (do_branch) { |
| 2740 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 2863 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| 2741 } else { | 2864 } else { |
| 2742 next_pc = current_pc + kBranchReturnOffset; | 2865 next_pc = current_pc + kBranchReturnOffset; |
| 2743 } | 2866 } |
| 2744 break; | 2867 break; |
| 2868 case BC1EQZ: |
| 2869 do_branch = (ft & 0x1) ? false : true; |
| 2870 execute_branch_delay_instruction = true; |
| 2871 // Set next_pc. |
| 2872 if (do_branch) { |
| 2873 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| 2874 } else { |
| 2875 next_pc = current_pc + kBranchReturnOffset; |
| 2876 } |
| 2877 break; |
| 2878 case BC1NEZ: |
| 2879 do_branch = (ft & 0x1) ? true : false; |
| 2880 execute_branch_delay_instruction = true; |
| 2881 // Set next_pc. |
| 2882 if (do_branch) { |
| 2883 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| 2884 } else { |
| 2885 next_pc = current_pc + kBranchReturnOffset; |
| 2886 } |
| 2887 break; |
| 2745 default: | 2888 default: |
| 2746 UNREACHABLE(); | 2889 UNREACHABLE(); |
| 2747 } | 2890 } |
| 2748 break; | 2891 break; |
| 2749 // ------------- REGIMM class. | 2892 // ------------- REGIMM class. |
| 2750 case REGIMM: | 2893 case REGIMM: |
| 2751 switch (instr->RtFieldRaw()) { | 2894 switch (instr->RtFieldRaw()) { |
| 2752 case BLTZ: | 2895 case BLTZ: |
| 2753 do_branch = (rs < 0); | 2896 do_branch = (rs < 0); |
| 2754 break; | 2897 break; |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3299 } | 3442 } |
| 3300 | 3443 |
| 3301 | 3444 |
| 3302 #undef UNSUPPORTED | 3445 #undef UNSUPPORTED |
| 3303 | 3446 |
| 3304 } } // namespace v8::internal | 3447 } } // namespace v8::internal |
| 3305 | 3448 |
| 3306 #endif // USE_SIMULATOR | 3449 #endif // USE_SIMULATOR |
| 3307 | 3450 |
| 3308 #endif // V8_TARGET_ARCH_MIPS64 | 3451 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |