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

Side by Side Diff: src/mips64/simulator-mips64.cc

Issue 1488613007: MIPS: Correct handling of Nan values on MIPS R6 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits.h> 5 #include <limits.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <cmath> 8 #include <cmath>
9 9
10 #if V8_TARGET_ARCH_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 break_instr_ = 0; 891 break_instr_ = 0;
892 892
893 // Set up architecture state. 893 // Set up architecture state.
894 // All registers are initialized to zero to start with. 894 // All registers are initialized to zero to start with.
895 for (int i = 0; i < kNumSimuRegisters; i++) { 895 for (int i = 0; i < kNumSimuRegisters; i++) {
896 registers_[i] = 0; 896 registers_[i] = 0;
897 } 897 }
898 for (int i = 0; i < kNumFPURegisters; i++) { 898 for (int i = 0; i < kNumFPURegisters; i++) {
899 FPUregisters_[i] = 0; 899 FPUregisters_[i] = 0;
900 } 900 }
901 FCSR_ = 0; 901
902 if (kArchVariant == kMips64r6) {
903 FCSR_ = kFCSRNaN2008FlagMask;
904 } else {
905 FCSR_ = 0;
906 }
902 907
903 // The sp is initialized to point to the bottom (high address) of the 908 // The sp is initialized to point to the bottom (high address) of the
904 // allocated stack area. To be safe in potential stack underflows we leave 909 // allocated stack area. To be safe in potential stack underflows we leave
905 // some buffer below. 910 // some buffer below.
906 registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64; 911 registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64;
907 // The ra and pc are initialized to a known bad value that will cause an 912 // The ra and pc are initialized to a known bad value that will cause an
908 // access violation if the simulator ever tries to execute it. 913 // access violation if the simulator ever tries to execute it.
909 registers_[pc] = bad_ra; 914 registers_[pc] = bad_ra;
910 registers_[ra] = bad_ra; 915 registers_[ra] = bad_ra;
911 InitializeCoverage(); 916 InitializeCoverage();
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 if (rounded > max_int32 || rounded < min_int32) { 1313 if (rounded > max_int32 || rounded < min_int32) {
1309 set_fcsr_bit(kFCSROverflowFlagBit, true); 1314 set_fcsr_bit(kFCSROverflowFlagBit, true);
1310 // The reference is not really clear but it seems this is required: 1315 // The reference is not really clear but it seems this is required:
1311 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1316 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1312 ret = true; 1317 ret = true;
1313 } 1318 }
1314 1319
1315 return ret; 1320 return ret;
1316 } 1321 }
1317 1322
1323 void Simulator::set_fpu_register_word_invalid_result(float original,
1324 float rounded) {
1325 if (FCSR_ & kFCSRNaN2008FlagMask) {
1326 double max_int32 = std::numeric_limits<int32_t>::max();
1327 double min_int32 = std::numeric_limits<int32_t>::min();
1328 if (std::isnan(original)) {
1329 set_fpu_register_word(fd_reg(), 0);
1330 } else if (rounded > max_int32) {
1331 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1332 } else if (rounded < min_int32) {
1333 set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
1334 } else {
1335 UNREACHABLE();
1336 }
1337 } else {
1338 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1339 }
1340 }
1341
1342
1343 void Simulator::set_fpu_register_invalid_result(float original, float rounded) {
1344 if (FCSR_ & kFCSRNaN2008FlagMask) {
1345 double max_int32 = std::numeric_limits<int32_t>::max();
1346 double min_int32 = std::numeric_limits<int32_t>::min();
1347 if (std::isnan(original)) {
1348 set_fpu_register(fd_reg(), 0);
1349 } else if (rounded > max_int32) {
1350 set_fpu_register(fd_reg(), kFPUInvalidResult);
1351 } else if (rounded < min_int32) {
1352 set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
1353 } else {
1354 UNREACHABLE();
1355 }
1356 } else {
1357 set_fpu_register(fd_reg(), kFPUInvalidResult);
1358 }
1359 }
1360
1361
1362 void Simulator::set_fpu_register_invalid_result64(float original,
1363 float rounded) {
1364 if (FCSR_ & kFCSRNaN2008FlagMask) {
1365 double max_int64 = std::numeric_limits<int64_t>::max();
1366 double min_int64 = std::numeric_limits<int64_t>::min();
1367 if (std::isnan(original)) {
1368 set_fpu_register(fd_reg(), 0);
1369 } else if (rounded > max_int64) {
1370 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1371 } else if (rounded < min_int64) {
1372 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
1373 } else {
1374 UNREACHABLE();
1375 }
1376 } else {
1377 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1378 }
1379 }
1380
1381
1382 void Simulator::set_fpu_register_word_invalid_result(double original,
1383 double rounded) {
1384 if (FCSR_ & kFCSRNaN2008FlagMask) {
1385 double max_int32 = std::numeric_limits<int32_t>::max();
1386 double min_int32 = std::numeric_limits<int32_t>::min();
1387 if (std::isnan(original)) {
1388 set_fpu_register_word(fd_reg(), 0);
1389 } else if (rounded > max_int32) {
1390 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1391 } else if (rounded < min_int32) {
1392 set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
1393 } else {
1394 UNREACHABLE();
1395 }
1396 } else {
1397 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1398 }
1399 }
1400
1401
1402 void Simulator::set_fpu_register_invalid_result(double original,
1403 double rounded) {
1404 if (FCSR_ & kFCSRNaN2008FlagMask) {
1405 double max_int32 = std::numeric_limits<int32_t>::max();
1406 double min_int32 = std::numeric_limits<int32_t>::min();
1407 if (std::isnan(original)) {
1408 set_fpu_register(fd_reg(), 0);
1409 } else if (rounded > max_int32) {
1410 set_fpu_register(fd_reg(), kFPUInvalidResult);
1411 } else if (rounded < min_int32) {
1412 set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
1413 } else {
1414 UNREACHABLE();
1415 }
1416 } else {
1417 set_fpu_register(fd_reg(), kFPUInvalidResult);
1418 }
1419 }
1420
1421
1422 void Simulator::set_fpu_register_invalid_result64(double original,
1423 double rounded) {
1424 if (FCSR_ & kFCSRNaN2008FlagMask) {
1425 double max_int64 = std::numeric_limits<int64_t>::max();
1426 double min_int64 = std::numeric_limits<int64_t>::min();
1427 if (std::isnan(original)) {
1428 set_fpu_register(fd_reg(), 0);
1429 } else if (rounded > max_int64) {
1430 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1431 } else if (rounded < min_int64) {
1432 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
1433 } else {
1434 UNREACHABLE();
1435 }
1436 } else {
1437 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1438 }
1439 }
1440
1318 1441
1319 // Sets the rounding error codes in FCSR based on the result of the rounding. 1442 // Sets the rounding error codes in FCSR based on the result of the rounding.
1320 // Returns true if the operation was invalid. 1443 // Returns true if the operation was invalid.
1321 bool Simulator::set_fcsr_round64_error(float original, float rounded) { 1444 bool Simulator::set_fcsr_round64_error(float original, float rounded) {
1322 bool ret = false; 1445 bool ret = false;
1323 double max_int64 = std::numeric_limits<int64_t>::max(); 1446 double max_int64 = std::numeric_limits<int64_t>::max();
1324 double min_int64 = std::numeric_limits<int64_t>::min(); 1447 double min_int64 = std::numeric_limits<int64_t>::min();
1325 1448
1326 if (!std::isfinite(original) || !std::isfinite(rounded)) { 1449 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1327 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1450 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
2364 set_fpu_register_float(fd_reg(), fResult); 2487 set_fpu_register_float(fd_reg(), fResult);
2365 2488
2366 break; 2489 break;
2367 } 2490 }
2368 case CVT_L_S: { 2491 case CVT_L_S: {
2369 float rounded; 2492 float rounded;
2370 int64_t result; 2493 int64_t result;
2371 round64_according_to_fcsr(fs, rounded, result, fs); 2494 round64_according_to_fcsr(fs, rounded, result, fs);
2372 set_fpu_register(fd_reg(), result); 2495 set_fpu_register(fd_reg(), result);
2373 if (set_fcsr_round64_error(fs, rounded)) { 2496 if (set_fcsr_round64_error(fs, rounded)) {
2374 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2497 set_fpu_register_invalid_result64(fs, rounded);
2375 } 2498 }
2376 break; 2499 break;
2377 } 2500 }
2378 case CVT_W_S: { 2501 case CVT_W_S: {
2379 float rounded; 2502 float rounded;
2380 int32_t result; 2503 int32_t result;
2381 round_according_to_fcsr(fs, rounded, result, fs); 2504 round_according_to_fcsr(fs, rounded, result, fs);
2382 set_fpu_register_word(fd_reg(), result); 2505 set_fpu_register_word(fd_reg(), result);
2383 if (set_fcsr_round_error(fs, rounded)) { 2506 if (set_fcsr_round_error(fs, rounded)) {
2384 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2507 set_fpu_register_word_invalid_result(fs, rounded);
2385 } 2508 }
2386 break; 2509 break;
2387 } 2510 }
2388 case TRUNC_W_S: { // Truncate single to word (round towards 0). 2511 case TRUNC_W_S: { // Truncate single to word (round towards 0).
2389 float rounded = trunc(fs); 2512 float rounded = trunc(fs);
2390 int32_t result = static_cast<int32_t>(rounded); 2513 int32_t result = static_cast<int32_t>(rounded);
2391 set_fpu_register_word(fd_reg(), result); 2514 set_fpu_register_word(fd_reg(), result);
2392 if (set_fcsr_round_error(fs, rounded)) { 2515 if (set_fcsr_round_error(fs, rounded)) {
2393 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2516 set_fpu_register_word_invalid_result(fs, rounded);
2394 } 2517 }
2395 } break; 2518 } break;
2396 case TRUNC_L_S: { // Mips64r2 instruction. 2519 case TRUNC_L_S: { // Mips64r2 instruction.
2397 float rounded = trunc(fs); 2520 float rounded = trunc(fs);
2398 int64_t result = static_cast<int64_t>(rounded); 2521 int64_t result = static_cast<int64_t>(rounded);
2399 set_fpu_register(fd_reg(), result); 2522 set_fpu_register(fd_reg(), result);
2400 if (set_fcsr_round64_error(fs, rounded)) { 2523 if (set_fcsr_round64_error(fs, rounded)) {
2401 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2524 set_fpu_register_invalid_result64(fs, rounded);
2402 } 2525 }
2403 break; 2526 break;
2404 } 2527 }
2405 case ROUND_W_S: { 2528 case ROUND_W_S: {
2406 float rounded = std::floor(fs + 0.5); 2529 float rounded = std::floor(fs + 0.5);
2407 int32_t result = static_cast<int32_t>(rounded); 2530 int32_t result = static_cast<int32_t>(rounded);
2408 if ((result & 1) != 0 && result - fs == 0.5) { 2531 if ((result & 1) != 0 && result - fs == 0.5) {
2409 // If the number is halfway between two integers, 2532 // If the number is halfway between two integers,
2410 // round to the even one. 2533 // round to the even one.
2411 result--; 2534 result--;
2412 } 2535 }
2413 set_fpu_register_word(fd_reg(), result); 2536 set_fpu_register_word(fd_reg(), result);
2414 if (set_fcsr_round_error(fs, rounded)) { 2537 if (set_fcsr_round_error(fs, rounded)) {
2415 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2538 set_fpu_register_word_invalid_result(fs, rounded);
2416 } 2539 }
2417 break; 2540 break;
2418 } 2541 }
2419 case ROUND_L_S: { // Mips64r2 instruction. 2542 case ROUND_L_S: { // Mips64r2 instruction.
2420 float rounded = std::floor(fs + 0.5); 2543 float rounded = std::floor(fs + 0.5);
2421 int64_t result = static_cast<int64_t>(rounded); 2544 int64_t result = static_cast<int64_t>(rounded);
2422 if ((result & 1) != 0 && result - fs == 0.5) { 2545 if ((result & 1) != 0 && result - fs == 0.5) {
2423 // If the number is halfway between two integers, 2546 // If the number is halfway between two integers,
2424 // round to the even one. 2547 // round to the even one.
2425 result--; 2548 result--;
2426 } 2549 }
2427 int64_t i64 = static_cast<int64_t>(result); 2550 int64_t i64 = static_cast<int64_t>(result);
2428 set_fpu_register(fd_reg(), i64); 2551 set_fpu_register(fd_reg(), i64);
2429 if (set_fcsr_round64_error(fs, rounded)) { 2552 if (set_fcsr_round64_error(fs, rounded)) {
2430 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2553 set_fpu_register_invalid_result64(fs, rounded);
2431 } 2554 }
2432 break; 2555 break;
2433 } 2556 }
2434 case FLOOR_L_S: { // Mips64r2 instruction. 2557 case FLOOR_L_S: { // Mips64r2 instruction.
2435 float rounded = floor(fs); 2558 float rounded = floor(fs);
2436 int64_t result = static_cast<int64_t>(rounded); 2559 int64_t result = static_cast<int64_t>(rounded);
2437 set_fpu_register(fd_reg(), result); 2560 set_fpu_register(fd_reg(), result);
2438 if (set_fcsr_round64_error(fs, rounded)) { 2561 if (set_fcsr_round64_error(fs, rounded)) {
2439 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2562 set_fpu_register_invalid_result64(fs, rounded);
2440 } 2563 }
2441 break; 2564 break;
2442 } 2565 }
2443 case FLOOR_W_S: // Round double to word towards negative infinity. 2566 case FLOOR_W_S: // Round double to word towards negative infinity.
2444 { 2567 {
2445 float rounded = std::floor(fs); 2568 float rounded = std::floor(fs);
2446 int32_t result = static_cast<int32_t>(rounded); 2569 int32_t result = static_cast<int32_t>(rounded);
2447 set_fpu_register_word(fd_reg(), result); 2570 set_fpu_register_word(fd_reg(), result);
2448 if (set_fcsr_round_error(fs, rounded)) { 2571 if (set_fcsr_round_error(fs, rounded)) {
2449 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2572 set_fpu_register_word_invalid_result(fs, rounded);
2450 } 2573 }
2451 } break; 2574 } break;
2452 case CEIL_W_S: // Round double to word towards positive infinity. 2575 case CEIL_W_S: // Round double to word towards positive infinity.
2453 { 2576 {
2454 float rounded = std::ceil(fs); 2577 float rounded = std::ceil(fs);
2455 int32_t result = static_cast<int32_t>(rounded); 2578 int32_t result = static_cast<int32_t>(rounded);
2456 set_fpu_register_word(fd_reg(), result); 2579 set_fpu_register_word(fd_reg(), result);
2457 if (set_fcsr_round_error(fs, rounded)) { 2580 if (set_fcsr_round_error(fs, rounded)) {
2458 set_fpu_register(fd_reg(), kFPUInvalidResult); 2581 set_fpu_register_invalid_result(fs, rounded);
2459 } 2582 }
2460 } break; 2583 } break;
2461 case CEIL_L_S: { // Mips64r2 instruction. 2584 case CEIL_L_S: { // Mips64r2 instruction.
2462 float rounded = ceil(fs); 2585 float rounded = ceil(fs);
2463 int64_t result = static_cast<int64_t>(rounded); 2586 int64_t result = static_cast<int64_t>(rounded);
2464 set_fpu_register(fd_reg(), result); 2587 set_fpu_register(fd_reg(), result);
2465 if (set_fcsr_round64_error(fs, rounded)) { 2588 if (set_fcsr_round64_error(fs, rounded)) {
2466 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2589 set_fpu_register_invalid_result64(fs, rounded);
2467 } 2590 }
2468 break; 2591 break;
2469 } 2592 }
2470 case MINA: 2593 case MINA:
2471 DCHECK(kArchVariant == kMips64r6); 2594 DCHECK(kArchVariant == kMips64r6);
2472 fs = get_fpu_register_float(fs_reg()); 2595 fs = get_fpu_register_float(fs_reg());
2473 if (std::isnan(fs) && std::isnan(ft)) { 2596 if (std::isnan(fs) && std::isnan(ft)) {
2474 set_fpu_register_float(fd_reg(), fs); 2597 set_fpu_register_float(fd_reg(), fs);
2475 } else if (std::isnan(fs) && !std::isnan(ft)) { 2598 } else if (std::isnan(fs) && !std::isnan(ft)) {
2476 set_fpu_register_float(fd_reg(), ft); 2599 set_fpu_register_float(fd_reg(), ft);
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 break; 2923 break;
2801 case C_ULE_D: 2924 case C_ULE_D:
2802 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2925 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2803 break; 2926 break;
2804 case CVT_W_D: { // Convert double to word. 2927 case CVT_W_D: { // Convert double to word.
2805 double rounded; 2928 double rounded;
2806 int32_t result; 2929 int32_t result;
2807 round_according_to_fcsr(fs, rounded, result, fs); 2930 round_according_to_fcsr(fs, rounded, result, fs);
2808 set_fpu_register_word(fd_reg(), result); 2931 set_fpu_register_word(fd_reg(), result);
2809 if (set_fcsr_round_error(fs, rounded)) { 2932 if (set_fcsr_round_error(fs, rounded)) {
2810 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2933 set_fpu_register_word_invalid_result(fs, rounded);
2811 } 2934 }
2812 break; 2935 break;
2813 } 2936 }
2814 case ROUND_W_D: // Round double to word (round half to even). 2937 case ROUND_W_D: // Round double to word (round half to even).
2815 { 2938 {
2816 double rounded = std::floor(fs + 0.5); 2939 double rounded = std::floor(fs + 0.5);
2817 int32_t result = static_cast<int32_t>(rounded); 2940 int32_t result = static_cast<int32_t>(rounded);
2818 if ((result & 1) != 0 && result - fs == 0.5) { 2941 if ((result & 1) != 0 && result - fs == 0.5) {
2819 // If the number is halfway between two integers, 2942 // If the number is halfway between two integers,
2820 // round to the even one. 2943 // round to the even one.
2821 result--; 2944 result--;
2822 } 2945 }
2823 set_fpu_register_word(fd_reg(), result); 2946 set_fpu_register_word(fd_reg(), result);
2824 if (set_fcsr_round_error(fs, rounded)) { 2947 if (set_fcsr_round_error(fs, rounded)) {
2825 set_fpu_register(fd_reg(), kFPUInvalidResult); 2948 set_fpu_register_invalid_result(fs, rounded);
2826 } 2949 }
2827 } break; 2950 } break;
2828 case TRUNC_W_D: // Truncate double to word (round towards 0). 2951 case TRUNC_W_D: // Truncate double to word (round towards 0).
2829 { 2952 {
2830 double rounded = trunc(fs); 2953 double rounded = trunc(fs);
2831 int32_t result = static_cast<int32_t>(rounded); 2954 int32_t result = static_cast<int32_t>(rounded);
2832 set_fpu_register_word(fd_reg(), result); 2955 set_fpu_register_word(fd_reg(), result);
2833 if (set_fcsr_round_error(fs, rounded)) { 2956 if (set_fcsr_round_error(fs, rounded)) {
2834 set_fpu_register(fd_reg(), kFPUInvalidResult); 2957 set_fpu_register_invalid_result(fs, rounded);
2835 } 2958 }
2836 } break; 2959 } break;
2837 case FLOOR_W_D: // Round double to word towards negative infinity. 2960 case FLOOR_W_D: // Round double to word towards negative infinity.
2838 { 2961 {
2839 double rounded = std::floor(fs); 2962 double rounded = std::floor(fs);
2840 int32_t result = static_cast<int32_t>(rounded); 2963 int32_t result = static_cast<int32_t>(rounded);
2841 set_fpu_register_word(fd_reg(), result); 2964 set_fpu_register_word(fd_reg(), result);
2842 if (set_fcsr_round_error(fs, rounded)) { 2965 if (set_fcsr_round_error(fs, rounded)) {
2843 set_fpu_register(fd_reg(), kFPUInvalidResult); 2966 set_fpu_register_invalid_result(fs, rounded);
2844 } 2967 }
2845 } break; 2968 } break;
2846 case CEIL_W_D: // Round double to word towards positive infinity. 2969 case CEIL_W_D: // Round double to word towards positive infinity.
2847 { 2970 {
2848 double rounded = std::ceil(fs); 2971 double rounded = std::ceil(fs);
2849 int32_t result = static_cast<int32_t>(rounded); 2972 int32_t result = static_cast<int32_t>(rounded);
2850 set_fpu_register_word(fd_reg(), result); 2973 set_fpu_register_word(fd_reg(), result);
2851 if (set_fcsr_round_error(fs, rounded)) { 2974 if (set_fcsr_round_error(fs, rounded)) {
2852 set_fpu_register(fd_reg(), kFPUInvalidResult); 2975 set_fpu_register_invalid_result(fs, rounded);
2853 } 2976 }
2854 } break; 2977 } break;
2855 case CVT_S_D: // Convert double to float (single). 2978 case CVT_S_D: // Convert double to float (single).
2856 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); 2979 set_fpu_register_float(fd_reg(), static_cast<float>(fs));
2857 break; 2980 break;
2858 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word. 2981 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word.
2859 double rounded; 2982 double rounded;
2860 int64_t result; 2983 int64_t result;
2861 round64_according_to_fcsr(fs, rounded, result, fs); 2984 round64_according_to_fcsr(fs, rounded, result, fs);
2862 set_fpu_register(fd_reg(), result); 2985 set_fpu_register(fd_reg(), result);
2863 if (set_fcsr_round64_error(fs, rounded)) { 2986 if (set_fcsr_round64_error(fs, rounded)) {
2864 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2987 set_fpu_register_invalid_result64(fs, rounded);
2865 } 2988 }
2866 break; 2989 break;
2867 } 2990 }
2868 case ROUND_L_D: { // Mips64r2 instruction. 2991 case ROUND_L_D: { // Mips64r2 instruction.
2869 double rounded = std::floor(fs + 0.5); 2992 double rounded = std::floor(fs + 0.5);
2870 int64_t result = static_cast<int64_t>(rounded); 2993 int64_t result = static_cast<int64_t>(rounded);
2871 if ((result & 1) != 0 && result - fs == 0.5) { 2994 if ((result & 1) != 0 && result - fs == 0.5) {
2872 // If the number is halfway between two integers, 2995 // If the number is halfway between two integers,
2873 // round to the even one. 2996 // round to the even one.
2874 result--; 2997 result--;
2875 } 2998 }
2876 int64_t i64 = static_cast<int64_t>(result); 2999 int64_t i64 = static_cast<int64_t>(result);
2877 set_fpu_register(fd_reg(), i64); 3000 set_fpu_register(fd_reg(), i64);
2878 if (set_fcsr_round64_error(fs, rounded)) { 3001 if (set_fcsr_round64_error(fs, rounded)) {
2879 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3002 set_fpu_register_invalid_result64(fs, rounded);
2880 } 3003 }
2881 break; 3004 break;
2882 } 3005 }
2883 case TRUNC_L_D: { // Mips64r2 instruction. 3006 case TRUNC_L_D: { // Mips64r2 instruction.
2884 double rounded = trunc(fs); 3007 double rounded = trunc(fs);
2885 int64_t result = static_cast<int64_t>(rounded); 3008 int64_t result = static_cast<int64_t>(rounded);
2886 set_fpu_register(fd_reg(), result); 3009 set_fpu_register(fd_reg(), result);
2887 if (set_fcsr_round64_error(fs, rounded)) { 3010 if (set_fcsr_round64_error(fs, rounded)) {
2888 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3011 set_fpu_register_invalid_result64(fs, rounded);
2889 } 3012 }
2890 break; 3013 break;
2891 } 3014 }
2892 case FLOOR_L_D: { // Mips64r2 instruction. 3015 case FLOOR_L_D: { // Mips64r2 instruction.
2893 double rounded = floor(fs); 3016 double rounded = floor(fs);
2894 int64_t result = static_cast<int64_t>(rounded); 3017 int64_t result = static_cast<int64_t>(rounded);
2895 set_fpu_register(fd_reg(), result); 3018 set_fpu_register(fd_reg(), result);
2896 if (set_fcsr_round64_error(fs, rounded)) { 3019 if (set_fcsr_round64_error(fs, rounded)) {
2897 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3020 set_fpu_register_invalid_result64(fs, rounded);
2898 } 3021 }
2899 break; 3022 break;
2900 } 3023 }
2901 case CEIL_L_D: { // Mips64r2 instruction. 3024 case CEIL_L_D: { // Mips64r2 instruction.
2902 double rounded = ceil(fs); 3025 double rounded = ceil(fs);
2903 int64_t result = static_cast<int64_t>(rounded); 3026 int64_t result = static_cast<int64_t>(rounded);
2904 set_fpu_register(fd_reg(), result); 3027 set_fpu_register(fd_reg(), result);
2905 if (set_fcsr_round64_error(fs, rounded)) { 3028 if (set_fcsr_round64_error(fs, rounded)) {
2906 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3029 set_fpu_register_invalid_result64(fs, rounded);
2907 } 3030 }
2908 break; 3031 break;
2909 } 3032 }
2910 case CLASS_D: { // Mips64r6 instruction 3033 case CLASS_D: { // Mips64r6 instruction
2911 // Convert double input to uint64_t for easier bit manipulation 3034 // Convert double input to uint64_t for easier bit manipulation
2912 uint64_t classed = bit_cast<uint64_t>(fs); 3035 uint64_t classed = bit_cast<uint64_t>(fs);
2913 3036
2914 // Extracting sign, exponent and mantissa from the input double 3037 // Extracting sign, exponent and mantissa from the input double
2915 uint32_t sign = (classed >> 63) & 1; 3038 uint32_t sign = (classed >> 63) & 1;
2916 uint32_t exponent = (classed >> 52) & 0x00000000000007ff; 3039 uint32_t exponent = (classed >> 52) & 0x00000000000007ff;
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3181 case MFC1: 3304 case MFC1:
3182 set_register(rt_reg(), 3305 set_register(rt_reg(),
3183 static_cast<int64_t>(get_fpu_register_word(fs_reg()))); 3306 static_cast<int64_t>(get_fpu_register_word(fs_reg())));
3184 break; 3307 break;
3185 case DMFC1: 3308 case DMFC1:
3186 set_register(rt_reg(), get_fpu_register(fs_reg())); 3309 set_register(rt_reg(), get_fpu_register(fs_reg()));
3187 break; 3310 break;
3188 case MFHC1: 3311 case MFHC1:
3189 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); 3312 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg()));
3190 break; 3313 break;
3191 case CTC1: 3314 case CTC1: {
3192 // At the moment only FCSR is supported. 3315 // At the moment only FCSR is supported.
3193 DCHECK(fs_reg() == kFCSRRegister); 3316 DCHECK(fs_reg() == kFCSRRegister);
3194 FCSR_ = static_cast<uint32_t>(rt()); 3317 uint32_t reg = static_cast<uint32_t>(rt());
3318 if (kArchVariant == kMips64r6) {
3319 FCSR_ = reg | kFCSRNaN2008FlagMask;
3320 } else {
3321 DCHECK(kArchVariant == kMips64r2);
3322 FCSR_ = reg & ~kFCSRNaN2008FlagMask;
3323 }
3195 break; 3324 break;
3325 }
3196 case MTC1: 3326 case MTC1:
3197 // Hardware writes upper 32-bits to zero on mtc1. 3327 // Hardware writes upper 32-bits to zero on mtc1.
3198 set_fpu_register_hi_word(fs_reg(), 0); 3328 set_fpu_register_hi_word(fs_reg(), 0);
3199 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt())); 3329 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt()));
3200 break; 3330 break;
3201 case DMTC1: 3331 case DMTC1:
3202 set_fpu_register(fs_reg(), rt()); 3332 set_fpu_register(fs_reg(), rt());
3203 break; 3333 break;
3204 case MTHC1: 3334 case MTHC1:
3205 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt())); 3335 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt()));
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
4590 } 4720 }
4591 4721
4592 4722
4593 #undef UNSUPPORTED 4723 #undef UNSUPPORTED
4594 } // namespace internal 4724 } // namespace internal
4595 } // namespace v8 4725 } // namespace v8
4596 4726
4597 #endif // USE_SIMULATOR 4727 #endif // USE_SIMULATOR
4598 4728
4599 #endif // V8_TARGET_ARCH_MIPS64 4729 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698