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 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1295 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) { | 1295 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) { |
1296 FCSR_ |= mode & kFPURoundingModeMask; | 1296 FCSR_ |= mode & kFPURoundingModeMask; |
1297 } | 1297 } |
1298 | 1298 |
1299 | 1299 |
1300 unsigned int Simulator::get_fcsr_rounding_mode() { | 1300 unsigned int Simulator::get_fcsr_rounding_mode() { |
1301 return FCSR_ & kFPURoundingModeMask; | 1301 return FCSR_ & kFPURoundingModeMask; |
1302 } | 1302 } |
1303 | 1303 |
1304 | 1304 |
| 1305 // Sets the rounding error codes in FCSR based on the result of the rounding. |
| 1306 // Returns true if the operation was invalid. |
1305 bool Simulator::set_fcsr_round_error(double original, double rounded) { | 1307 bool Simulator::set_fcsr_round_error(double original, double rounded) { |
1306 bool ret = false; | 1308 bool ret = false; |
1307 double max_int32 = std::numeric_limits<int32_t>::max(); | 1309 double max_int32 = std::numeric_limits<int32_t>::max(); |
1308 double min_int32 = std::numeric_limits<int32_t>::min(); | 1310 double min_int32 = std::numeric_limits<int32_t>::min(); |
1309 | 1311 |
1310 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1312 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
1311 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1313 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1312 ret = true; | 1314 ret = true; |
1313 } | 1315 } |
1314 | 1316 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 set_fcsr_bit(kFCSROverflowFlagBit, true); | 1359 set_fcsr_bit(kFCSROverflowFlagBit, true); |
1358 // The reference is not really clear but it seems this is required: | 1360 // The reference is not really clear but it seems this is required: |
1359 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1361 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1360 ret = true; | 1362 ret = true; |
1361 } | 1363 } |
1362 | 1364 |
1363 return ret; | 1365 return ret; |
1364 } | 1366 } |
1365 | 1367 |
1366 | 1368 |
| 1369 // Sets the rounding error codes in FCSR based on the result of the rounding. |
| 1370 // Returns true if the operation was invalid. |
1367 bool Simulator::set_fcsr_round_error(float original, float rounded) { | 1371 bool Simulator::set_fcsr_round_error(float original, float rounded) { |
1368 bool ret = false; | 1372 bool ret = false; |
1369 double max_int32 = std::numeric_limits<int32_t>::max(); | 1373 double max_int32 = std::numeric_limits<int32_t>::max(); |
1370 double min_int32 = std::numeric_limits<int32_t>::min(); | 1374 double min_int32 = std::numeric_limits<int32_t>::min(); |
1371 | 1375 |
1372 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1376 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
1373 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1377 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
1374 ret = true; | 1378 ret = true; |
1375 } | 1379 } |
1376 | 1380 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 rounded_int = static_cast<int32_t>(rounded); | 1464 rounded_int = static_cast<int32_t>(rounded); |
1461 break; | 1465 break; |
1462 case kRoundToMinusInf: | 1466 case kRoundToMinusInf: |
1463 rounded = std::floor(fs); | 1467 rounded = std::floor(fs); |
1464 rounded_int = static_cast<int32_t>(rounded); | 1468 rounded_int = static_cast<int32_t>(rounded); |
1465 break; | 1469 break; |
1466 } | 1470 } |
1467 } | 1471 } |
1468 | 1472 |
1469 | 1473 |
| 1474 void Simulator::round_according_to_fcsr(float toRound, float& rounded, |
| 1475 int32_t& rounded_int, float fs) { |
| 1476 // 0 RN (round to nearest): Round a result to the nearest |
| 1477 // representable value; if the result is exactly halfway between |
| 1478 // two representable values, round to zero. Behave like round_w_d. |
| 1479 |
| 1480 // 1 RZ (round toward zero): Round a result to the closest |
| 1481 // representable value whose absolute value is less than or |
| 1482 // equal to the infinitely accurate result. Behave like trunc_w_d. |
| 1483 |
| 1484 // 2 RP (round up, or toward infinity): Round a result to the |
| 1485 // next representable value up. Behave like ceil_w_d. |
| 1486 |
| 1487 // 3 RD (round down, or toward −infinity): Round a result to |
| 1488 // the next representable value down. Behave like floor_w_d. |
| 1489 switch (get_fcsr_rounding_mode()) { |
| 1490 case kRoundToNearest: |
| 1491 rounded = std::floor(fs + 0.5); |
| 1492 rounded_int = static_cast<int32_t>(rounded); |
| 1493 if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) { |
| 1494 // If the number is halfway between two integers, |
| 1495 // round to the even one. |
| 1496 rounded_int--; |
| 1497 } |
| 1498 break; |
| 1499 case kRoundToZero: |
| 1500 rounded = trunc(fs); |
| 1501 rounded_int = static_cast<int32_t>(rounded); |
| 1502 break; |
| 1503 case kRoundToPlusInf: |
| 1504 rounded = std::ceil(fs); |
| 1505 rounded_int = static_cast<int32_t>(rounded); |
| 1506 break; |
| 1507 case kRoundToMinusInf: |
| 1508 rounded = std::floor(fs); |
| 1509 rounded_int = static_cast<int32_t>(rounded); |
| 1510 break; |
| 1511 } |
| 1512 } |
| 1513 |
| 1514 |
| 1515 void Simulator::round64_according_to_fcsr(double toRound, double& rounded, |
| 1516 int64_t& rounded_int, double fs) { |
| 1517 // 0 RN (round to nearest): Round a result to the nearest |
| 1518 // representable value; if the result is exactly halfway between |
| 1519 // two representable values, round to zero. Behave like round_w_d. |
| 1520 |
| 1521 // 1 RZ (round toward zero): Round a result to the closest |
| 1522 // representable value whose absolute value is less than or. |
| 1523 // equal to the infinitely accurate result. Behave like trunc_w_d. |
| 1524 |
| 1525 // 2 RP (round up, or toward +infinity): Round a result to the |
| 1526 // next representable value up. Behave like ceil_w_d. |
| 1527 |
| 1528 // 3 RN (round down, or toward −infinity): Round a result to |
| 1529 // the next representable value down. Behave like floor_w_d. |
| 1530 switch (FCSR_ & 3) { |
| 1531 case kRoundToNearest: |
| 1532 rounded = std::floor(fs + 0.5); |
| 1533 rounded_int = static_cast<int64_t>(rounded); |
| 1534 if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) { |
| 1535 // If the number is halfway between two integers, |
| 1536 // round to the even one. |
| 1537 rounded_int--; |
| 1538 } |
| 1539 break; |
| 1540 case kRoundToZero: |
| 1541 rounded = trunc(fs); |
| 1542 rounded_int = static_cast<int64_t>(rounded); |
| 1543 break; |
| 1544 case kRoundToPlusInf: |
| 1545 rounded = std::ceil(fs); |
| 1546 rounded_int = static_cast<int64_t>(rounded); |
| 1547 break; |
| 1548 case kRoundToMinusInf: |
| 1549 rounded = std::floor(fs); |
| 1550 rounded_int = static_cast<int64_t>(rounded); |
| 1551 break; |
| 1552 } |
| 1553 } |
| 1554 |
| 1555 |
| 1556 void Simulator::round64_according_to_fcsr(float toRound, float& rounded, |
| 1557 int64_t& rounded_int, float fs) { |
| 1558 // 0 RN (round to nearest): Round a result to the nearest |
| 1559 // representable value; if the result is exactly halfway between |
| 1560 // two representable values, round to zero. Behave like round_w_d. |
| 1561 |
| 1562 // 1 RZ (round toward zero): Round a result to the closest |
| 1563 // representable value whose absolute value is less than or. |
| 1564 // equal to the infinitely accurate result. Behave like trunc_w_d. |
| 1565 |
| 1566 // 2 RP (round up, or toward +infinity): Round a result to the |
| 1567 // next representable value up. Behave like ceil_w_d. |
| 1568 |
| 1569 // 3 RN (round down, or toward −infinity): Round a result to |
| 1570 // the next representable value down. Behave like floor_w_d. |
| 1571 switch (FCSR_ & 3) { |
| 1572 case kRoundToNearest: |
| 1573 rounded = std::floor(fs + 0.5); |
| 1574 rounded_int = static_cast<int64_t>(rounded); |
| 1575 if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) { |
| 1576 // If the number is halfway between two integers, |
| 1577 // round to the even one. |
| 1578 rounded_int--; |
| 1579 } |
| 1580 break; |
| 1581 case kRoundToZero: |
| 1582 rounded = trunc(fs); |
| 1583 rounded_int = static_cast<int64_t>(rounded); |
| 1584 break; |
| 1585 case kRoundToPlusInf: |
| 1586 rounded = std::ceil(fs); |
| 1587 rounded_int = static_cast<int64_t>(rounded); |
| 1588 break; |
| 1589 case kRoundToMinusInf: |
| 1590 rounded = std::floor(fs); |
| 1591 rounded_int = static_cast<int64_t>(rounded); |
| 1592 break; |
| 1593 } |
| 1594 } |
| 1595 |
| 1596 |
1470 // Raw access to the PC register. | 1597 // Raw access to the PC register. |
1471 void Simulator::set_pc(int32_t value) { | 1598 void Simulator::set_pc(int32_t value) { |
1472 pc_modified_ = true; | 1599 pc_modified_ = true; |
1473 registers_[pc] = value; | 1600 registers_[pc] = value; |
1474 } | 1601 } |
1475 | 1602 |
1476 | 1603 |
1477 bool Simulator::has_bad_pc() const { | 1604 bool Simulator::has_bad_pc() const { |
1478 return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc)); | 1605 return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc)); |
1479 } | 1606 } |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2277 case EXT: { // Mips32r2 instruction. | 2404 case EXT: { // Mips32r2 instruction. |
2278 // Interpret rd field as 5-bit msb of extract. | 2405 // Interpret rd field as 5-bit msb of extract. |
2279 uint16_t msb = rd_reg; | 2406 uint16_t msb = rd_reg; |
2280 // Interpret sa field as 5-bit lsb of extract. | 2407 // Interpret sa field as 5-bit lsb of extract. |
2281 uint16_t lsb = sa; | 2408 uint16_t lsb = sa; |
2282 uint16_t size = msb + 1; | 2409 uint16_t size = msb + 1; |
2283 uint32_t mask = (1 << size) - 1; | 2410 uint32_t mask = (1 << size) - 1; |
2284 *alu_out = (rs_u & (mask << lsb)) >> lsb; | 2411 *alu_out = (rs_u & (mask << lsb)) >> lsb; |
2285 break; | 2412 break; |
2286 } | 2413 } |
| 2414 case BITSWAP: { // Mips32r6 instruction |
| 2415 uint32_t input = static_cast<uint32_t>(rt); |
| 2416 uint32_t output = 0; |
| 2417 uint8_t i_byte, o_byte; |
| 2418 |
| 2419 // Reverse the bit in byte for each individual byte |
| 2420 for (int i = 0; i < 4; i++) { |
| 2421 output = output >> 8; |
| 2422 i_byte = input & 0xff; |
| 2423 |
| 2424 // Fast way to reverse bits in byte |
| 2425 // Devised by Sean Anderson, July 13, 2001 |
| 2426 o_byte = static_cast<uint8_t>(((i_byte * 0x0802LU & 0x22110LU) | |
| 2427 (i_byte * 0x8020LU & 0x88440LU)) * |
| 2428 0x10101LU >> |
| 2429 16); |
| 2430 |
| 2431 output = output | (static_cast<uint32_t>(o_byte << 24)); |
| 2432 input = input >> 8; |
| 2433 } |
| 2434 |
| 2435 *alu_out = static_cast<int32_t>(output); |
| 2436 break; |
| 2437 } |
2287 default: | 2438 default: |
2288 UNREACHABLE(); | 2439 UNREACHABLE(); |
2289 } | 2440 } |
2290 break; | 2441 break; |
2291 default: | 2442 default: |
2292 UNREACHABLE(); | 2443 UNREACHABLE(); |
2293 } | 2444 } |
2294 } | 2445 } |
2295 | 2446 |
2296 | 2447 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2563 int32_t result = static_cast<int32_t>(rounded); | 2714 int32_t result = static_cast<int32_t>(rounded); |
2564 set_fpu_register_word(fd_reg, result); | 2715 set_fpu_register_word(fd_reg, result); |
2565 if (set_fcsr_round_error(fs, rounded)) { | 2716 if (set_fcsr_round_error(fs, rounded)) { |
2566 set_fpu_register_word(fd_reg, kFPUInvalidResult); | 2717 set_fpu_register_word(fd_reg, kFPUInvalidResult); |
2567 } | 2718 } |
2568 } break; | 2719 } break; |
2569 case CVT_S_D: // Convert double to float (single). | 2720 case CVT_S_D: // Convert double to float (single). |
2570 set_fpu_register_float(fd_reg, static_cast<float>(fs)); | 2721 set_fpu_register_float(fd_reg, static_cast<float>(fs)); |
2571 break; | 2722 break; |
2572 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. | 2723 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. |
2573 double rounded = trunc(fs); | |
2574 i64 = static_cast<int64_t>(rounded); | |
2575 if (IsFp64Mode()) { | 2724 if (IsFp64Mode()) { |
2576 set_fpu_register(fd_reg, i64); | 2725 int64_t result; |
| 2726 double rounded; |
| 2727 round64_according_to_fcsr(fs, rounded, result, fs); |
| 2728 set_fpu_register(fd_reg, result); |
| 2729 if (set_fcsr_round64_error(fs, rounded)) { |
| 2730 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2731 } |
2577 } else { | 2732 } else { |
2578 UNSUPPORTED(); | 2733 UNSUPPORTED(); |
2579 } | 2734 } |
2580 break; | 2735 break; |
| 2736 break; |
2581 } | 2737 } |
2582 case TRUNC_L_D: { // Mips32r2 instruction. | 2738 case TRUNC_L_D: { // Mips32r2 instruction. |
2583 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 2739 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
2584 double rounded = trunc(fs); | 2740 double rounded = trunc(fs); |
2585 i64 = static_cast<int64_t>(rounded); | 2741 i64 = static_cast<int64_t>(rounded); |
2586 if (IsFp64Mode()) { | 2742 if (IsFp64Mode()) { |
2587 set_fpu_register(fd_reg, i64); | 2743 set_fpu_register(fd_reg, i64); |
2588 if (set_fcsr_round64_error(fs, rounded)) { | 2744 if (set_fcsr_round64_error(fs, rounded)) { |
2589 set_fpu_register(fd_reg, kFPU64InvalidResult); | 2745 set_fpu_register(fd_reg, kFPU64InvalidResult); |
2590 } | 2746 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2634 if (IsFp64Mode()) { | 2790 if (IsFp64Mode()) { |
2635 set_fpu_register(fd_reg, i64); | 2791 set_fpu_register(fd_reg, i64); |
2636 if (set_fcsr_round64_error(fs, rounded)) { | 2792 if (set_fcsr_round64_error(fs, rounded)) { |
2637 set_fpu_register(fd_reg, kFPU64InvalidResult); | 2793 set_fpu_register(fd_reg, kFPU64InvalidResult); |
2638 } | 2794 } |
2639 } else { | 2795 } else { |
2640 UNSUPPORTED(); | 2796 UNSUPPORTED(); |
2641 } | 2797 } |
2642 break; | 2798 break; |
2643 } | 2799 } |
2644 case C_F_D: | 2800 case CLASS_D: { // Mips32r6 instruction |
2645 UNIMPLEMENTED_MIPS(); | 2801 // Convert double input to uint64_t for easier bit manipulation |
| 2802 uint64_t classed = bit_cast<uint64_t>(fs); |
| 2803 |
| 2804 // Extracting sign, exponent and mantissa from the input double |
| 2805 uint32_t sign = (classed >> 63) & 1; |
| 2806 uint32_t exponent = (classed >> 52) & 0x00000000000007ff; |
| 2807 uint64_t mantissa = classed & 0x000fffffffffffff; |
| 2808 uint64_t result; |
| 2809 double dResult; |
| 2810 |
| 2811 // Setting flags if input double is negative infinity, |
| 2812 // positive infinity, negative zero or positive zero |
| 2813 bool negInf = (classed == 0xFFF0000000000000); |
| 2814 bool posInf = (classed == 0x7FF0000000000000); |
| 2815 bool negZero = (classed == 0x8000000000000000); |
| 2816 bool posZero = (classed == 0x0000000000000000); |
| 2817 |
| 2818 bool signalingNan; |
| 2819 bool quietNan; |
| 2820 bool negSubnorm; |
| 2821 bool posSubnorm; |
| 2822 bool negNorm; |
| 2823 bool posNorm; |
| 2824 |
| 2825 // Setting flags if double is NaN |
| 2826 signalingNan = false; |
| 2827 quietNan = false; |
| 2828 if (!negInf && !posInf && exponent == 0x7ff) { |
| 2829 quietNan = ((mantissa & 0x0008000000000000) != 0) && |
| 2830 ((mantissa & (0x0008000000000000 - 1)) == 0); |
| 2831 signalingNan = !quietNan; |
| 2832 } |
| 2833 |
| 2834 // Setting flags if double is subnormal number |
| 2835 posSubnorm = false; |
| 2836 negSubnorm = false; |
| 2837 if ((exponent == 0) && (mantissa != 0)) { |
| 2838 DCHECK(sign == 0 || sign == 1); |
| 2839 posSubnorm = (sign == 0); |
| 2840 negSubnorm = (sign == 1); |
| 2841 } |
| 2842 |
| 2843 // Setting flags if double is normal number |
| 2844 posNorm = false; |
| 2845 negNorm = false; |
| 2846 if (!posSubnorm && !negSubnorm && !posInf && !negInf && !signalingNan && |
| 2847 !quietNan && !negZero && !posZero) { |
| 2848 DCHECK(sign == 0 || sign == 1); |
| 2849 posNorm = (sign == 0); |
| 2850 negNorm = (sign == 1); |
| 2851 } |
| 2852 |
| 2853 // Calculating result according to description of CLASS.D instruction |
| 2854 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
| 2855 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
| 2856 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
| 2857 |
| 2858 DCHECK(result != 0); |
| 2859 |
| 2860 dResult = bit_cast<double>(result); |
| 2861 set_fpu_register_double(fd_reg, dResult); |
| 2862 |
2646 break; | 2863 break; |
| 2864 } |
| 2865 case C_F_D: { |
| 2866 set_fcsr_bit(fcsr_cc, false); |
| 2867 break; |
| 2868 } |
2647 default: | 2869 default: |
2648 UNREACHABLE(); | 2870 UNREACHABLE(); |
2649 } | 2871 } |
2650 } | 2872 } |
2651 | 2873 |
2652 | 2874 |
2653 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, int32_t& alu_out, | 2875 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, int32_t& alu_out, |
2654 const int32_t& fd_reg, | 2876 const int32_t& fd_reg, |
2655 const int32_t& fs_reg) { | 2877 const int32_t& fs_reg, |
| 2878 const int32_t& ft_reg) { |
| 2879 float fs = get_fpu_register_float(fs_reg); |
| 2880 float ft = get_fpu_register_float(ft_reg); |
2656 switch (instr->FunctionFieldRaw()) { | 2881 switch (instr->FunctionFieldRaw()) { |
2657 case CVT_S_W: // Convert word to float (single). | 2882 case CVT_S_W: // Convert word to float (single). |
2658 alu_out = get_fpu_register_signed_word(fs_reg); | 2883 alu_out = get_fpu_register_signed_word(fs_reg); |
2659 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); | 2884 set_fpu_register_float(fd_reg, static_cast<float>(alu_out)); |
2660 break; | 2885 break; |
2661 case CVT_D_W: // Convert word to double. | 2886 case CVT_D_W: // Convert word to double. |
2662 alu_out = get_fpu_register_signed_word(fs_reg); | 2887 alu_out = get_fpu_register_signed_word(fs_reg); |
2663 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); | 2888 set_fpu_register_double(fd_reg, static_cast<double>(alu_out)); |
2664 break; | 2889 break; |
2665 default: // Mips64r6 CMP.S instructions unimplemented. | 2890 case CMP_AF: |
| 2891 set_fpu_register_word(fd_reg, 0); |
| 2892 break; |
| 2893 case CMP_UN: |
| 2894 if (std::isnan(fs) || std::isnan(ft)) { |
| 2895 set_fpu_register_word(fd_reg, -1); |
| 2896 } else { |
| 2897 set_fpu_register_word(fd_reg, 0); |
| 2898 } |
| 2899 break; |
| 2900 case CMP_EQ: |
| 2901 if (fs == ft) { |
| 2902 set_fpu_register_word(fd_reg, -1); |
| 2903 } else { |
| 2904 set_fpu_register_word(fd_reg, 0); |
| 2905 } |
| 2906 break; |
| 2907 case CMP_UEQ: |
| 2908 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2909 set_fpu_register_word(fd_reg, -1); |
| 2910 } else { |
| 2911 set_fpu_register_word(fd_reg, 0); |
| 2912 } |
| 2913 break; |
| 2914 case CMP_LT: |
| 2915 if (fs < ft) { |
| 2916 set_fpu_register_word(fd_reg, -1); |
| 2917 } else { |
| 2918 set_fpu_register_word(fd_reg, 0); |
| 2919 } |
| 2920 break; |
| 2921 case CMP_ULT: |
| 2922 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2923 set_fpu_register_word(fd_reg, -1); |
| 2924 } else { |
| 2925 set_fpu_register_word(fd_reg, 0); |
| 2926 } |
| 2927 break; |
| 2928 case CMP_LE: |
| 2929 if (fs <= ft) { |
| 2930 set_fpu_register_word(fd_reg, -1); |
| 2931 } else { |
| 2932 set_fpu_register_word(fd_reg, 0); |
| 2933 } |
| 2934 break; |
| 2935 case CMP_ULE: |
| 2936 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2937 set_fpu_register_word(fd_reg, -1); |
| 2938 } else { |
| 2939 set_fpu_register_word(fd_reg, 0); |
| 2940 } |
| 2941 break; |
| 2942 case CMP_OR: |
| 2943 if (!std::isnan(fs) && !std::isnan(ft)) { |
| 2944 set_fpu_register_word(fd_reg, -1); |
| 2945 } else { |
| 2946 set_fpu_register_word(fd_reg, 0); |
| 2947 } |
| 2948 break; |
| 2949 case CMP_UNE: |
| 2950 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 2951 set_fpu_register_word(fd_reg, -1); |
| 2952 } else { |
| 2953 set_fpu_register_word(fd_reg, 0); |
| 2954 } |
| 2955 break; |
| 2956 case CMP_NE: |
| 2957 if (fs != ft) { |
| 2958 set_fpu_register_word(fd_reg, -1); |
| 2959 } else { |
| 2960 set_fpu_register_word(fd_reg, 0); |
| 2961 } |
| 2962 break; |
| 2963 default: |
2666 UNREACHABLE(); | 2964 UNREACHABLE(); |
2667 } | 2965 } |
2668 } | 2966 } |
2669 | 2967 |
2670 | 2968 |
2671 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, | 2969 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, |
2672 const int32_t& ft_reg, | 2970 const int32_t& ft_reg, |
2673 const int32_t& fs_reg, | 2971 const int32_t& fs_reg, |
2674 const int32_t& fd_reg) { | 2972 const int32_t& fd_reg) { |
2675 float fs, ft, fd; | 2973 float fs, ft, fd; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 case RSQRT_S: { | 3045 case RSQRT_S: { |
2748 float result = 1.0 / fast_sqrt(fs); | 3046 float result = 1.0 / fast_sqrt(fs); |
2749 set_fpu_register_float(fd_reg, result); | 3047 set_fpu_register_float(fd_reg, result); |
2750 break; | 3048 break; |
2751 } | 3049 } |
2752 case RECIP_S: { | 3050 case RECIP_S: { |
2753 float result = 1.0 / fs; | 3051 float result = 1.0 / fs; |
2754 set_fpu_register_float(fd_reg, result); | 3052 set_fpu_register_float(fd_reg, result); |
2755 break; | 3053 break; |
2756 } | 3054 } |
| 3055 case C_F_D: |
| 3056 set_fcsr_bit(fcsr_cc, false); |
| 3057 break; |
2757 case C_UN_D: | 3058 case C_UN_D: |
2758 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 3059 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
2759 break; | 3060 break; |
2760 case C_EQ_D: | 3061 case C_EQ_D: |
2761 set_fcsr_bit(fcsr_cc, (fs == ft)); | 3062 set_fcsr_bit(fcsr_cc, (fs == ft)); |
2762 break; | 3063 break; |
2763 case C_UEQ_D: | 3064 case C_UEQ_D: |
2764 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 3065 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
2765 break; | 3066 break; |
2766 case C_OLT_D: | 3067 case C_OLT_D: |
2767 set_fcsr_bit(fcsr_cc, (fs < ft)); | 3068 set_fcsr_bit(fcsr_cc, (fs < ft)); |
2768 break; | 3069 break; |
2769 case C_ULT_D: | 3070 case C_ULT_D: |
2770 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 3071 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
2771 break; | 3072 break; |
2772 case C_OLE_D: | 3073 case C_OLE_D: |
2773 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 3074 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
2774 break; | 3075 break; |
2775 case C_ULE_D: | 3076 case C_ULE_D: |
2776 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 3077 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
2777 break; | 3078 break; |
2778 case CVT_D_S: | 3079 case CVT_D_S: |
2779 set_fpu_register_double(fd_reg, static_cast<double>(fs)); | 3080 set_fpu_register_double(fd_reg, static_cast<double>(fs)); |
2780 break; | 3081 break; |
2781 case SEL: | 3082 case SEL: |
2782 DCHECK(IsMipsArchVariant(kMips32r6)); | 3083 DCHECK(IsMipsArchVariant(kMips32r6)); |
2783 set_fpu_register_float(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); | 3084 set_fpu_register_float(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); |
2784 break; | 3085 break; |
| 3086 case CLASS_S: { // Mips32r6 instruction |
| 3087 // Convert float input to uint32_t for easier bit manipulation |
| 3088 float fs = get_fpu_register_float(fs_reg); |
| 3089 uint32_t classed = bit_cast<uint32_t>(fs); |
| 3090 |
| 3091 // Extracting sign, exponent and mantissa from the input float |
| 3092 uint32_t sign = (classed >> 31) & 1; |
| 3093 uint32_t exponent = (classed >> 23) & 0x000000ff; |
| 3094 uint32_t mantissa = classed & 0x007fffff; |
| 3095 uint32_t result; |
| 3096 float fResult; |
| 3097 |
| 3098 // Setting flags if input float is negative infinity, |
| 3099 // positive infinity, negative zero or positive zero |
| 3100 bool negInf = (classed == 0xFF800000); |
| 3101 bool posInf = (classed == 0x7F800000); |
| 3102 bool negZero = (classed == 0x80000000); |
| 3103 bool posZero = (classed == 0x00000000); |
| 3104 |
| 3105 bool signalingNan; |
| 3106 bool quietNan; |
| 3107 bool negSubnorm; |
| 3108 bool posSubnorm; |
| 3109 bool negNorm; |
| 3110 bool posNorm; |
| 3111 |
| 3112 // Setting flags if float is NaN |
| 3113 signalingNan = false; |
| 3114 quietNan = false; |
| 3115 if (!negInf && !posInf && (exponent == 0xff)) { |
| 3116 quietNan = ((mantissa & 0x00200000) == 0) && |
| 3117 ((mantissa & (0x00200000 - 1)) == 0); |
| 3118 signalingNan = !quietNan; |
| 3119 } |
| 3120 |
| 3121 // Setting flags if float is subnormal number |
| 3122 posSubnorm = false; |
| 3123 negSubnorm = false; |
| 3124 if ((exponent == 0) && (mantissa != 0)) { |
| 3125 DCHECK(sign == 0 || sign == 1); |
| 3126 posSubnorm = (sign == 0); |
| 3127 negSubnorm = (sign == 1); |
| 3128 } |
| 3129 |
| 3130 // Setting flags if float is normal number |
| 3131 posNorm = false; |
| 3132 negNorm = false; |
| 3133 if (!posSubnorm && !negSubnorm && !posInf && !negInf && !signalingNan && |
| 3134 !quietNan && !negZero && !posZero) { |
| 3135 DCHECK(sign == 0 || sign == 1); |
| 3136 posNorm = (sign == 0); |
| 3137 negNorm = (sign == 1); |
| 3138 } |
| 3139 |
| 3140 // Calculating result according to description of CLASS.S instruction |
| 3141 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
| 3142 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
| 3143 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
| 3144 |
| 3145 DCHECK(result != 0); |
| 3146 |
| 3147 fResult = bit_cast<float>(result); |
| 3148 set_fpu_register_float(fd_reg, fResult); |
| 3149 |
| 3150 break; |
| 3151 } |
2785 case SELEQZ_C: | 3152 case SELEQZ_C: |
2786 DCHECK(IsMipsArchVariant(kMips32r6)); | 3153 DCHECK(IsMipsArchVariant(kMips32r6)); |
2787 set_fpu_register_float( | 3154 set_fpu_register_float( |
2788 fd_reg, (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg) : 0.0); | 3155 fd_reg, (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg) : 0.0); |
2789 break; | 3156 break; |
2790 case SELNEZ_C: | 3157 case SELNEZ_C: |
2791 DCHECK(IsMipsArchVariant(kMips32r6)); | 3158 DCHECK(IsMipsArchVariant(kMips32r6)); |
2792 set_fpu_register_float( | 3159 set_fpu_register_float( |
2793 fd_reg, (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg) : 0.0); | 3160 fd_reg, (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg) : 0.0); |
2794 break; | 3161 break; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2987 if (fabs(fs) < fabs(ft)) { | 3354 if (fabs(fs) < fabs(ft)) { |
2988 result = ft; | 3355 result = ft; |
2989 } else if (fabs(fs) > fabs(ft)) { | 3356 } else if (fabs(fs) > fabs(ft)) { |
2990 result = fs; | 3357 result = fs; |
2991 } else { | 3358 } else { |
2992 result = (fs > ft ? fs : ft); | 3359 result = (fs > ft ? fs : ft); |
2993 } | 3360 } |
2994 set_fpu_register_float(fd_reg, result); | 3361 set_fpu_register_float(fd_reg, result); |
2995 } | 3362 } |
2996 break; | 3363 break; |
| 3364 case CVT_L_S: { |
| 3365 if (IsFp64Mode()) { |
| 3366 int64_t result; |
| 3367 float rounded; |
| 3368 round64_according_to_fcsr(fs, rounded, result, fs); |
| 3369 set_fpu_register(fd_reg, result); |
| 3370 if (set_fcsr_round64_error(fs, rounded)) { |
| 3371 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 3372 } |
| 3373 } else { |
| 3374 UNSUPPORTED(); |
| 3375 } |
| 3376 break; |
| 3377 } |
| 3378 case CVT_W_S: { |
| 3379 float rounded; |
| 3380 int32_t result; |
| 3381 round_according_to_fcsr(fs, rounded, result, fs); |
| 3382 set_fpu_register_word(fd_reg, result); |
| 3383 if (set_fcsr_round_error(fs, rounded)) { |
| 3384 set_fpu_register_word(fd_reg, kFPUInvalidResult); |
| 3385 } |
| 3386 break; |
| 3387 } |
2997 default: | 3388 default: |
2998 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S | 3389 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S |
2999 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. | 3390 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
3000 UNREACHABLE(); | 3391 UNREACHABLE(); |
3001 } | 3392 } |
3002 } | 3393 } |
3003 | 3394 |
3004 | 3395 |
3005 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, | 3396 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, |
3006 const int32_t& ft_reg, | 3397 const int32_t& ft_reg, |
3007 const int32_t& fs_reg, | 3398 const int32_t& fs_reg, |
3008 const int32_t& fd_reg) { | 3399 const int32_t& fd_reg) { |
3009 double fs = get_fpu_register_double(fs_reg); | 3400 double fs = get_fpu_register_double(fs_reg); |
3010 double ft = get_fpu_register_double(ft_reg); | 3401 double ft = get_fpu_register_double(ft_reg); |
3011 switch (instr->FunctionFieldRaw()) { | 3402 switch (instr->FunctionFieldRaw()) { |
3012 case CVT_D_L: // Mips32r2 instruction. | 3403 case CVT_D_L: // Mips32r2 instruction. |
3013 // Watch the signs here, we want 2 32-bit vals | 3404 // Watch the signs here, we want 2 32-bit vals |
3014 // to make a sign-64. | 3405 // to make a sign-64. |
3015 int64_t i64; | 3406 int64_t i64; |
3016 if (IsFp64Mode()) { | 3407 if (IsFp64Mode()) { |
3017 i64 = get_fpu_register(fs_reg); | 3408 i64 = get_fpu_register(fs_reg); |
3018 } else { | 3409 } else { |
3019 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg)); | 3410 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg)); |
3020 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg + 1)) << 32; | 3411 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg + 1)) << 32; |
3021 } | 3412 } |
3022 set_fpu_register_double(fd_reg, static_cast<double>(i64)); | 3413 set_fpu_register_double(fd_reg, static_cast<double>(i64)); |
3023 break; | 3414 break; |
3024 case CVT_S_L: | 3415 case CVT_S_L: |
3025 UNIMPLEMENTED_MIPS(); | 3416 if (IsFp64Mode()) { |
| 3417 i64 = get_fpu_register(fs_reg); |
| 3418 } else { |
| 3419 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg)); |
| 3420 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg + 1)) << 32; |
| 3421 } |
| 3422 set_fpu_register_float(fd_reg, static_cast<float>(i64)); |
3026 break; | 3423 break; |
3027 case CMP_AF: // Mips64r6 CMP.D instructions. | 3424 case CMP_AF: // Mips64r6 CMP.D instructions. |
3028 UNIMPLEMENTED_MIPS(); | 3425 set_fpu_register(fd_reg, 0); |
3029 break; | 3426 break; |
3030 case CMP_UN: | 3427 case CMP_UN: |
3031 if (std::isnan(fs) || std::isnan(ft)) { | 3428 if (std::isnan(fs) || std::isnan(ft)) { |
3032 set_fpu_register(fd_reg, -1); | 3429 set_fpu_register(fd_reg, -1); |
3033 } else { | 3430 } else { |
3034 set_fpu_register(fd_reg, 0); | 3431 set_fpu_register(fd_reg, 0); |
3035 } | 3432 } |
3036 break; | 3433 break; |
3037 case CMP_EQ: | 3434 case CMP_EQ: |
3038 if (fs == ft) { | 3435 if (fs == ft) { |
(...skipping 30 matching lines...) Expand all Loading... |
3069 set_fpu_register(fd_reg, 0); | 3466 set_fpu_register(fd_reg, 0); |
3070 } | 3467 } |
3071 break; | 3468 break; |
3072 case CMP_ULE: | 3469 case CMP_ULE: |
3073 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3470 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
3074 set_fpu_register(fd_reg, -1); | 3471 set_fpu_register(fd_reg, -1); |
3075 } else { | 3472 } else { |
3076 set_fpu_register(fd_reg, 0); | 3473 set_fpu_register(fd_reg, 0); |
3077 } | 3474 } |
3078 break; | 3475 break; |
3079 default: // CMP_OR CMP_UNE CMP_NE UNIMPLEMENTED. | 3476 case CMP_OR: |
| 3477 if (!std::isnan(fs) && !std::isnan(ft)) { |
| 3478 set_fpu_register(fd_reg, -1); |
| 3479 } else { |
| 3480 set_fpu_register(fd_reg, 0); |
| 3481 } |
| 3482 break; |
| 3483 case CMP_UNE: |
| 3484 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3485 set_fpu_register(fd_reg, -1); |
| 3486 } else { |
| 3487 set_fpu_register(fd_reg, 0); |
| 3488 } |
| 3489 break; |
| 3490 case CMP_NE: |
| 3491 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { |
| 3492 set_fpu_register(fd_reg, -1); |
| 3493 } else { |
| 3494 set_fpu_register(fd_reg, 0); |
| 3495 } |
| 3496 break; |
| 3497 default: |
3080 UNREACHABLE(); | 3498 UNREACHABLE(); |
3081 } | 3499 } |
3082 } | 3500 } |
3083 | 3501 |
3084 | 3502 |
3085 void Simulator::DecodeTypeRegisterCOP1( | 3503 void Simulator::DecodeTypeRegisterCOP1( |
3086 Instruction* instr, const int32_t& rs_reg, const int32_t& rs, | 3504 Instruction* instr, const int32_t& rs_reg, const int32_t& rs, |
3087 const uint32_t& rs_u, const int32_t& rt_reg, const int32_t& rt, | 3505 const uint32_t& rs_u, const int32_t& rt_reg, const int32_t& rt, |
3088 const uint32_t& rt_u, const int32_t& rd_reg, const int32_t& fr_reg, | 3506 const uint32_t& rt_u, const int32_t& rd_reg, const int32_t& fr_reg, |
3089 const int32_t& fs_reg, const int32_t& ft_reg, const int32_t& fd_reg, | 3507 const int32_t& fs_reg, const int32_t& ft_reg, const int32_t& fd_reg, |
(...skipping 23 matching lines...) Expand all Loading... |
3113 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]); | 3531 set_fpu_register_hi_word(fs_reg, registers_[rt_reg]); |
3114 break; | 3532 break; |
3115 case S: { | 3533 case S: { |
3116 DecodeTypeRegisterSRsType(instr, ft_reg, fs_reg, fd_reg); | 3534 DecodeTypeRegisterSRsType(instr, ft_reg, fs_reg, fd_reg); |
3117 break; | 3535 break; |
3118 } | 3536 } |
3119 case D: | 3537 case D: |
3120 DecodeTypeRegisterDRsType(instr, fr_reg, fs_reg, ft_reg, fd_reg); | 3538 DecodeTypeRegisterDRsType(instr, fr_reg, fs_reg, ft_reg, fd_reg); |
3121 break; | 3539 break; |
3122 case W: | 3540 case W: |
3123 DecodeTypeRegisterWRsType(instr, alu_out, fd_reg, fs_reg); | 3541 DecodeTypeRegisterWRsType(instr, alu_out, fd_reg, fs_reg, ft_reg); |
3124 break; | 3542 break; |
3125 case L: | 3543 case L: |
3126 DecodeTypeRegisterLRsType(instr, ft_reg, fs_reg, fd_reg); | 3544 DecodeTypeRegisterLRsType(instr, ft_reg, fs_reg, fd_reg); |
3127 break; | 3545 break; |
3128 default: | 3546 default: |
3129 UNREACHABLE(); | 3547 UNREACHABLE(); |
3130 } | 3548 } |
3131 } | 3549 } |
3132 | 3550 |
3133 | 3551 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3328 set_register(HI, Unpredictable); | 3746 set_register(HI, Unpredictable); |
3329 break; | 3747 break; |
3330 default: // For other special2 opcodes we do the default operation. | 3748 default: // For other special2 opcodes we do the default operation. |
3331 set_register(rd_reg, alu_out); | 3749 set_register(rd_reg, alu_out); |
3332 } | 3750 } |
3333 } | 3751 } |
3334 | 3752 |
3335 | 3753 |
3336 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, | 3754 void Simulator::DecodeTypeRegisterSPECIAL3(Instruction* instr, |
3337 const int32_t& rt_reg, | 3755 const int32_t& rt_reg, |
| 3756 const int32_t& rd_reg, |
3338 int32_t& alu_out) { | 3757 int32_t& alu_out) { |
3339 switch (instr->FunctionFieldRaw()) { | 3758 switch (instr->FunctionFieldRaw()) { |
3340 case INS: | 3759 case INS: |
3341 // Ins instr leaves result in Rt, rather than Rd. | 3760 // Ins instr leaves result in Rt, rather than Rd. |
3342 set_register(rt_reg, alu_out); | 3761 set_register(rt_reg, alu_out); |
3343 break; | 3762 break; |
3344 case EXT: | 3763 case EXT: |
3345 // Ext instr leaves result in Rt, rather than Rd. | 3764 // Ext instr leaves result in Rt, rather than Rd. |
3346 set_register(rt_reg, alu_out); | 3765 set_register(rt_reg, alu_out); |
3347 break; | 3766 break; |
| 3767 case BITSWAP: |
| 3768 set_register(rd_reg, alu_out); |
| 3769 break; |
3348 default: | 3770 default: |
3349 UNREACHABLE(); | 3771 UNREACHABLE(); |
3350 } | 3772 } |
3351 } | 3773 } |
3352 | 3774 |
3353 | 3775 |
3354 void Simulator::DecodeTypeRegister(Instruction* instr) { | 3776 void Simulator::DecodeTypeRegister(Instruction* instr) { |
3355 // Instruction fields. | 3777 // Instruction fields. |
3356 const Opcode op = instr->OpcodeFieldRaw(); | 3778 const Opcode op = instr->OpcodeFieldRaw(); |
3357 const int32_t rs_reg = instr->RsValue(); | 3779 const int32_t rs_reg = instr->RsValue(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3405 case SPECIAL: | 3827 case SPECIAL: |
3406 DecodeTypeRegisterSPECIAL(instr, rs_reg, rs, rs_u, rt_reg, rt, rt_u, | 3828 DecodeTypeRegisterSPECIAL(instr, rs_reg, rs, rs_u, rt_reg, rt, rt_u, |
3407 rd_reg, fr_reg, fs_reg, ft_reg, fd_reg, i64hilo, | 3829 rd_reg, fr_reg, fs_reg, ft_reg, fd_reg, i64hilo, |
3408 u64hilo, alu_out, do_interrupt, current_pc, | 3830 u64hilo, alu_out, do_interrupt, current_pc, |
3409 next_pc, return_addr_reg); | 3831 next_pc, return_addr_reg); |
3410 break; | 3832 break; |
3411 case SPECIAL2: | 3833 case SPECIAL2: |
3412 DecodeTypeRegisterSPECIAL2(instr, rd_reg, alu_out); | 3834 DecodeTypeRegisterSPECIAL2(instr, rd_reg, alu_out); |
3413 break; | 3835 break; |
3414 case SPECIAL3: | 3836 case SPECIAL3: |
3415 DecodeTypeRegisterSPECIAL3(instr, rt_reg, alu_out); | 3837 DecodeTypeRegisterSPECIAL3(instr, rt_reg, rd_reg, alu_out); |
3416 break; | 3838 break; |
3417 // Unimplemented opcodes raised an error in the configuration step before, | 3839 // Unimplemented opcodes raised an error in the configuration step before, |
3418 // so we can use the default here to set the destination register in common | 3840 // so we can use the default here to set the destination register in common |
3419 // cases. | 3841 // cases. |
3420 default: | 3842 default: |
3421 set_register(rd_reg, alu_out); | 3843 set_register(rd_reg, alu_out); |
3422 } | 3844 } |
3423 } | 3845 } |
3424 | 3846 |
3425 | 3847 |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4009 } | 4431 } |
4010 | 4432 |
4011 | 4433 |
4012 #undef UNSUPPORTED | 4434 #undef UNSUPPORTED |
4013 | 4435 |
4014 } } // namespace v8::internal | 4436 } } // namespace v8::internal |
4015 | 4437 |
4016 #endif // USE_SIMULATOR | 4438 #endif // USE_SIMULATOR |
4017 | 4439 |
4018 #endif // V8_TARGET_ARCH_MIPS | 4440 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |