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 |
paul.l...
2014/07/29 14:58:04
nit: end comment with period, here and DMULT below
dusmil.imgtec
2014/07/29 17:39:12
Done.
| |
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 |
paul.l...
2014/07/29 14:58:04
nit: trailing period on comment.
dusmil.imgtec
2014/07/29 17:39:12
Done.
| |
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 kMips64r1: |
2593 // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1), | 2688 case kMips64r2: |
2594 // return INT_MIN which is what the hardware does. | 2689 case kLoongson: |
2595 if (rs == INT_MIN && rt == -1) { | 2690 // Divide by zero and overflow was not checked in the |
2596 set_register(LO, INT_MIN); | 2691 // configuration step - div and divu do not raise exceptions. On |
2597 set_register(HI, 0); | 2692 // division by 0 the result will be UNPREDICTABLE. On overflow |
2598 } else if (rt != 0) { | 2693 // (INT_MIN/-1), return INT_MIN which is what the hardware does. |
2599 set_register(LO, rs / rt); | 2694 if (rs == INT_MIN && rt == -1) { |
2600 set_register(HI, rs % rt); | 2695 set_register(LO, INT_MIN); |
2696 set_register(HI, 0); | |
2697 } else if (rt != 0) { | |
2698 set_register(LO, rs / rt); | |
2699 set_register(HI, rs % rt); | |
2700 } | |
2701 break; | |
2702 case kMips64r6: | |
2703 switch (instr->SaValue()) { | |
2704 case DIV_OP: | |
2705 if (rs == INT_MIN && rt == -1) { | |
2706 set_register(rd_reg, INT_MIN); | |
2707 } else if (rt != 0) { | |
2708 set_register(rd_reg, rs / rt); | |
2709 } | |
2710 break; | |
2711 case MOD_OP: | |
2712 if (rs == INT_MIN && rt == -1) { | |
2713 set_register(rd_reg, 0); | |
2714 } else if (rt != 0) { | |
2715 set_register(rd_reg, rs % rt); | |
2716 } | |
2717 break; | |
2718 default: | |
2719 UNIMPLEMENTED_MIPS(); | |
2720 break; | |
2721 } | |
2722 break; | |
2723 default: | |
2724 break; | |
2601 } | 2725 } |
2602 break; | 2726 break; |
2603 case DIVU: | 2727 case DIVU: |
2604 if (rt_u != 0) { | 2728 if (rt_u != 0) { |
2605 set_register(LO, rs_u / rt_u); | 2729 set_register(LO, rs_u / rt_u); |
2606 set_register(HI, rs_u % rt_u); | 2730 set_register(HI, rs_u % rt_u); |
2607 } | 2731 } |
2608 break; | 2732 break; |
2609 // Break and trap instructions. | 2733 // Break and trap instructions. |
2610 case BREAK: | 2734 case BREAK: |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2689 void Simulator::DecodeTypeImmediate(Instruction* instr) { | 2813 void Simulator::DecodeTypeImmediate(Instruction* instr) { |
2690 // Instruction fields. | 2814 // Instruction fields. |
2691 Opcode op = instr->OpcodeFieldRaw(); | 2815 Opcode op = instr->OpcodeFieldRaw(); |
2692 int64_t rs = get_register(instr->RsValue()); | 2816 int64_t rs = get_register(instr->RsValue()); |
2693 uint64_t rs_u = static_cast<uint64_t>(rs); | 2817 uint64_t rs_u = static_cast<uint64_t>(rs); |
2694 int64_t rt_reg = instr->RtValue(); // Destination register. | 2818 int64_t rt_reg = instr->RtValue(); // Destination register. |
2695 int64_t rt = get_register(rt_reg); | 2819 int64_t rt = get_register(rt_reg); |
2696 int16_t imm16 = instr->Imm16Value(); | 2820 int16_t imm16 = instr->Imm16Value(); |
2697 | 2821 |
2698 int32_t ft_reg = instr->FtValue(); // Destination register. | 2822 int32_t ft_reg = instr->FtValue(); // Destination register. |
2823 int64_t ft = get_fpu_register(ft_reg); | |
2699 | 2824 |
2700 // Zero extended immediate. | 2825 // Zero extended immediate. |
2701 uint32_t oe_imm16 = 0xffff & imm16; | 2826 uint32_t oe_imm16 = 0xffff & imm16; |
2702 // Sign extended immediate. | 2827 // Sign extended immediate. |
2703 int32_t se_imm16 = imm16; | 2828 int32_t se_imm16 = imm16; |
2704 | 2829 |
2705 // Get current pc. | 2830 // Get current pc. |
2706 int64_t current_pc = get_pc(); | 2831 int64_t current_pc = get_pc(); |
2707 // Next pc. | 2832 // Next pc. |
2708 int64_t next_pc = bad_ra; | 2833 int64_t next_pc = bad_ra; |
(...skipping 26 matching lines...) Expand all Loading... | |
2735 cc_value = test_fcsr_bit(fcsr_cc); | 2860 cc_value = test_fcsr_bit(fcsr_cc); |
2736 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; | 2861 do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value; |
2737 execute_branch_delay_instruction = true; | 2862 execute_branch_delay_instruction = true; |
2738 // Set next_pc. | 2863 // Set next_pc. |
2739 if (do_branch) { | 2864 if (do_branch) { |
2740 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 2865 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
2741 } else { | 2866 } else { |
2742 next_pc = current_pc + kBranchReturnOffset; | 2867 next_pc = current_pc + kBranchReturnOffset; |
2743 } | 2868 } |
2744 break; | 2869 break; |
2870 case BC1EQZ: | |
2871 do_branch = (ft & 0x1) ? false : true; | |
2872 execute_branch_delay_instruction = true; | |
2873 // Set next_pc. | |
2874 if (do_branch) { | |
2875 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | |
2876 } else { | |
2877 next_pc = current_pc + kBranchReturnOffset; | |
2878 } | |
2879 break; | |
2880 case BC1NEZ: | |
2881 do_branch = (ft & 0x1) ? true : false; | |
2882 execute_branch_delay_instruction = true; | |
2883 // Set next_pc. | |
2884 if (do_branch) { | |
2885 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | |
2886 } else { | |
2887 next_pc = current_pc + kBranchReturnOffset; | |
2888 } | |
2889 break; | |
2745 default: | 2890 default: |
2746 UNREACHABLE(); | 2891 UNREACHABLE(); |
2747 } | 2892 } |
2748 break; | 2893 break; |
2749 // ------------- REGIMM class. | 2894 // ------------- REGIMM class. |
2750 case REGIMM: | 2895 case REGIMM: |
2751 switch (instr->RtFieldRaw()) { | 2896 switch (instr->RtFieldRaw()) { |
2752 case BLTZ: | 2897 case BLTZ: |
2753 do_branch = (rs < 0); | 2898 do_branch = (rs < 0); |
2754 break; | 2899 break; |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3299 } | 3444 } |
3300 | 3445 |
3301 | 3446 |
3302 #undef UNSUPPORTED | 3447 #undef UNSUPPORTED |
3303 | 3448 |
3304 } } // namespace v8::internal | 3449 } } // namespace v8::internal |
3305 | 3450 |
3306 #endif // USE_SIMULATOR | 3451 #endif // USE_SIMULATOR |
3307 | 3452 |
3308 #endif // V8_TARGET_ARCH_MIPS64 | 3453 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |