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 |