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

Side by Side Diff: src/mips/simulator-mips.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_MIPS 10 #if V8_TARGET_ARCH_MIPS
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 break_instr_ = 0; 961 break_instr_ = 0;
962 962
963 // Set up architecture state. 963 // Set up architecture state.
964 // All registers are initialized to zero to start with. 964 // All registers are initialized to zero to start with.
965 for (int i = 0; i < kNumSimuRegisters; i++) { 965 for (int i = 0; i < kNumSimuRegisters; i++) {
966 registers_[i] = 0; 966 registers_[i] = 0;
967 } 967 }
968 for (int i = 0; i < kNumFPURegisters; i++) { 968 for (int i = 0; i < kNumFPURegisters; i++) {
969 FPUregisters_[i] = 0; 969 FPUregisters_[i] = 0;
970 } 970 }
971 FCSR_ = 0; 971 if (IsMipsArchVariant(kMips32r6)) {
972 FCSR_ = kFCSRNaN2008FlagMask;
973 } else {
974 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2));
975 FCSR_ = 0;
976 }
972 977
973 // The sp is initialized to point to the bottom (high address) of the 978 // The sp is initialized to point to the bottom (high address) of the
974 // allocated stack area. To be safe in potential stack underflows we leave 979 // allocated stack area. To be safe in potential stack underflows we leave
975 // some buffer below. 980 // some buffer below.
976 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64; 981 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64;
977 // The ra and pc are initialized to a known bad value that will cause an 982 // The ra and pc are initialized to a known bad value that will cause an
978 // access violation if the simulator ever tries to execute it. 983 // access violation if the simulator ever tries to execute it.
979 registers_[pc] = bad_ra; 984 registers_[pc] = bad_ra;
980 registers_[ra] = bad_ra; 985 registers_[ra] = bad_ra;
981 InitializeCoverage(); 986 InitializeCoverage();
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) { 1294 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) {
1290 FCSR_ |= mode & kFPURoundingModeMask; 1295 FCSR_ |= mode & kFPURoundingModeMask;
1291 } 1296 }
1292 1297
1293 1298
1294 unsigned int Simulator::get_fcsr_rounding_mode() { 1299 unsigned int Simulator::get_fcsr_rounding_mode() {
1295 return FCSR_ & kFPURoundingModeMask; 1300 return FCSR_ & kFPURoundingModeMask;
1296 } 1301 }
1297 1302
1298 1303
1304 void Simulator::set_fpu_register_word_invalid_result(float original,
1305 float rounded) {
1306 if (FCSR_ & kFCSRNaN2008FlagMask) {
1307 double max_int32 = std::numeric_limits<int32_t>::max();
1308 double min_int32 = std::numeric_limits<int32_t>::min();
1309 if (std::isnan(original)) {
1310 set_fpu_register_word(fd_reg(), 0);
1311 } else if (rounded > max_int32) {
1312 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1313 } else if (rounded < min_int32) {
1314 set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
1315 } else {
1316 UNREACHABLE();
1317 }
1318 } else {
1319 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1320 }
1321 }
1322
1323
1324 void Simulator::set_fpu_register_invalid_result(float original, 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(fd_reg(), 0);
1330 } else if (rounded > max_int32) {
1331 set_fpu_register(fd_reg(), kFPUInvalidResult);
1332 } else if (rounded < min_int32) {
1333 set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
1334 } else {
1335 UNREACHABLE();
1336 }
1337 } else {
1338 set_fpu_register(fd_reg(), kFPUInvalidResult);
1339 }
1340 }
1341
1342
1343 void Simulator::set_fpu_register_invalid_result64(float original,
1344 float rounded) {
1345 if (FCSR_ & kFCSRNaN2008FlagMask) {
1346 double max_int64 = std::numeric_limits<int64_t>::max();
1347 double min_int64 = std::numeric_limits<int64_t>::min();
1348 if (std::isnan(original)) {
1349 set_fpu_register(fd_reg(), 0);
1350 } else if (rounded > max_int64) {
1351 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1352 } else if (rounded < min_int64) {
1353 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
1354 } else {
1355 UNREACHABLE();
1356 }
1357 } else {
1358 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1359 }
1360 }
1361
1362
1363 void Simulator::set_fpu_register_word_invalid_result(double original,
1364 double rounded) {
1365 if (FCSR_ & kFCSRNaN2008FlagMask) {
1366 double max_int32 = std::numeric_limits<int32_t>::max();
1367 double min_int32 = std::numeric_limits<int32_t>::min();
1368 if (std::isnan(original)) {
1369 set_fpu_register_word(fd_reg(), 0);
1370 } else if (rounded > max_int32) {
1371 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1372 } else if (rounded < min_int32) {
1373 set_fpu_register_word(fd_reg(), kFPUInvalidResultNegative);
1374 } else {
1375 UNREACHABLE();
1376 }
1377 } else {
1378 set_fpu_register_word(fd_reg(), kFPUInvalidResult);
1379 }
1380 }
1381
1382
1383 void Simulator::set_fpu_register_invalid_result(double original,
1384 double rounded) {
1385 if (FCSR_ & kFCSRNaN2008FlagMask) {
1386 double max_int32 = std::numeric_limits<int32_t>::max();
1387 double min_int32 = std::numeric_limits<int32_t>::min();
1388 if (std::isnan(original)) {
1389 set_fpu_register(fd_reg(), 0);
1390 } else if (rounded > max_int32) {
1391 set_fpu_register(fd_reg(), kFPUInvalidResult);
1392 } else if (rounded < min_int32) {
1393 set_fpu_register(fd_reg(), kFPUInvalidResultNegative);
1394 } else {
1395 UNREACHABLE();
1396 }
1397 } else {
1398 set_fpu_register(fd_reg(), kFPUInvalidResult);
1399 }
1400 }
1401
1402
1403 void Simulator::set_fpu_register_invalid_result64(double original,
1404 double rounded) {
1405 if (FCSR_ & kFCSRNaN2008FlagMask) {
1406 double max_int64 = std::numeric_limits<int64_t>::max();
1407 double min_int64 = std::numeric_limits<int64_t>::min();
1408 if (std::isnan(original)) {
1409 set_fpu_register(fd_reg(), 0);
1410 } else if (rounded > max_int64) {
1411 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1412 } else if (rounded < min_int64) {
1413 set_fpu_register(fd_reg(), kFPU64InvalidResultNegative);
1414 } else {
1415 UNREACHABLE();
1416 }
1417 } else {
1418 set_fpu_register(fd_reg(), kFPU64InvalidResult);
1419 }
1420 }
1421
1422
1299 // Sets the rounding error codes in FCSR based on the result of the rounding. 1423 // Sets the rounding error codes in FCSR based on the result of the rounding.
1300 // Returns true if the operation was invalid. 1424 // Returns true if the operation was invalid.
1301 bool Simulator::set_fcsr_round_error(double original, double rounded) { 1425 bool Simulator::set_fcsr_round_error(double original, double rounded) {
1302 bool ret = false; 1426 bool ret = false;
1303 double max_int32 = std::numeric_limits<int32_t>::max(); 1427 double max_int32 = std::numeric_limits<int32_t>::max();
1304 double min_int32 = std::numeric_limits<int32_t>::min(); 1428 double min_int32 = std::numeric_limits<int32_t>::min();
1305 1429
1306 if (!std::isfinite(original) || !std::isfinite(rounded)) { 1430 if (!std::isfinite(original) || !std::isfinite(rounded)) {
1307 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); 1431 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1308 ret = true; 1432 ret = true;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 case kRoundToNearest: 1567 case kRoundToNearest:
1444 rounded = std::floor(fs + 0.5); 1568 rounded = std::floor(fs + 0.5);
1445 rounded_int = static_cast<int32_t>(rounded); 1569 rounded_int = static_cast<int32_t>(rounded);
1446 if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) { 1570 if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
1447 // If the number is halfway between two integers, 1571 // If the number is halfway between two integers,
1448 // round to the even one. 1572 // round to the even one.
1449 rounded_int--; 1573 rounded_int--;
1450 } 1574 }
1451 break; 1575 break;
1452 case kRoundToZero: 1576 case kRoundToZero:
1577 printf("kRoundToZero");
1453 rounded = trunc(fs); 1578 rounded = trunc(fs);
1454 rounded_int = static_cast<int32_t>(rounded); 1579 rounded_int = static_cast<int32_t>(rounded);
1580 printf("Rounded int = %d\n", rounded_int);
paul.l... 2015/12/02 02:49:51 Leftover debugging prints? Please remove, here and
1455 break; 1581 break;
1456 case kRoundToPlusInf: 1582 case kRoundToPlusInf:
1457 rounded = std::ceil(fs); 1583 rounded = std::ceil(fs);
1458 rounded_int = static_cast<int32_t>(rounded); 1584 rounded_int = static_cast<int32_t>(rounded);
1459 break; 1585 break;
1460 case kRoundToMinusInf: 1586 case kRoundToMinusInf:
1461 rounded = std::floor(fs); 1587 rounded = std::floor(fs);
1462 rounded_int = static_cast<int32_t>(rounded); 1588 rounded_int = static_cast<int32_t>(rounded);
1463 break; 1589 break;
1464 } 1590 }
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 break; 2534 break;
2409 case C_ULE_D: 2535 case C_ULE_D:
2410 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2536 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2411 break; 2537 break;
2412 case CVT_W_D: { // Convert double to word. 2538 case CVT_W_D: { // Convert double to word.
2413 double rounded; 2539 double rounded;
2414 int32_t result; 2540 int32_t result;
2415 round_according_to_fcsr(fs, rounded, result, fs); 2541 round_according_to_fcsr(fs, rounded, result, fs);
2416 set_fpu_register_word(fd_reg(), result); 2542 set_fpu_register_word(fd_reg(), result);
2417 if (set_fcsr_round_error(fs, rounded)) { 2543 if (set_fcsr_round_error(fs, rounded)) {
2418 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2544 set_fpu_register_word_invalid_result(fs, rounded);
2419 } 2545 }
2420 } break; 2546 } break;
2421 case ROUND_W_D: // Round double to word (round half to even). 2547 case ROUND_W_D: // Round double to word (round half to even).
2422 { 2548 {
2423 double rounded = std::floor(fs + 0.5); 2549 double rounded = std::floor(fs + 0.5);
2424 int32_t result = static_cast<int32_t>(rounded); 2550 int32_t result = static_cast<int32_t>(rounded);
2425 if ((result & 1) != 0 && result - fs == 0.5) { 2551 if ((result & 1) != 0 && result - fs == 0.5) {
2426 // If the number is halfway between two integers, 2552 // If the number is halfway between two integers,
2427 // round to the even one. 2553 // round to the even one.
2428 result--; 2554 result--;
2429 } 2555 }
2430 set_fpu_register_word(fd_reg(), result); 2556 set_fpu_register_word(fd_reg(), result);
2431 if (set_fcsr_round_error(fs, rounded)) { 2557 if (set_fcsr_round_error(fs, rounded)) {
2432 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2558 set_fpu_register_word_invalid_result(fs, rounded);
2433 } 2559 }
2434 } break; 2560 } break;
2435 case TRUNC_W_D: // Truncate double to word (round towards 0). 2561 case TRUNC_W_D: // Truncate double to word (round towards 0).
2436 { 2562 {
2437 double rounded = trunc(fs); 2563 double rounded = trunc(fs);
2438 int32_t result = static_cast<int32_t>(rounded); 2564 int32_t result = static_cast<int32_t>(rounded);
2439 set_fpu_register_word(fd_reg(), result); 2565 set_fpu_register_word(fd_reg(), result);
2440 if (set_fcsr_round_error(fs, rounded)) { 2566 if (set_fcsr_round_error(fs, rounded)) {
2441 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2567 set_fpu_register_word_invalid_result(fs, rounded);
2442 } 2568 }
2443 } break; 2569 } break;
2444 case FLOOR_W_D: // Round double to word towards negative infinity. 2570 case FLOOR_W_D: // Round double to word towards negative infinity.
2445 { 2571 {
2446 double rounded = std::floor(fs); 2572 double rounded = std::floor(fs);
2447 int32_t result = static_cast<int32_t>(rounded); 2573 int32_t result = static_cast<int32_t>(rounded);
2448 set_fpu_register_word(fd_reg(), result); 2574 set_fpu_register_word(fd_reg(), result);
2449 if (set_fcsr_round_error(fs, rounded)) { 2575 if (set_fcsr_round_error(fs, rounded)) {
2450 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2576 set_fpu_register_word_invalid_result(fs, rounded);
2451 } 2577 }
2452 } break; 2578 } break;
2453 case CEIL_W_D: // Round double to word towards positive infinity. 2579 case CEIL_W_D: // Round double to word towards positive infinity.
2454 { 2580 {
2455 double rounded = std::ceil(fs); 2581 double rounded = std::ceil(fs);
2456 int32_t result = static_cast<int32_t>(rounded); 2582 int32_t result = static_cast<int32_t>(rounded);
2457 set_fpu_register_word(fd_reg(), result); 2583 set_fpu_register_word(fd_reg(), result);
2458 if (set_fcsr_round_error(fs, rounded)) { 2584 if (set_fcsr_round_error(fs, rounded)) {
2459 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 2585 set_fpu_register_word_invalid_result(fs, rounded);
2460 } 2586 }
2461 } break; 2587 } break;
2462 case CVT_S_D: // Convert double to float (single). 2588 case CVT_S_D: // Convert double to float (single).
2463 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); 2589 set_fpu_register_float(fd_reg(), static_cast<float>(fs));
2464 break; 2590 break;
2465 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. 2591 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
2466 if (IsFp64Mode()) { 2592 if (IsFp64Mode()) {
2467 int64_t result; 2593 int64_t result;
2468 double rounded; 2594 double rounded;
2469 round64_according_to_fcsr(fs, rounded, result, fs); 2595 round64_according_to_fcsr(fs, rounded, result, fs);
2470 set_fpu_register(fd_reg(), result); 2596 set_fpu_register(fd_reg(), result);
2471 if (set_fcsr_round64_error(fs, rounded)) { 2597 if (set_fcsr_round64_error(fs, rounded)) {
2472 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2598 set_fpu_register_invalid_result64(fs, rounded);
2473 } 2599 }
2474 } else { 2600 } else {
2475 UNSUPPORTED(); 2601 UNSUPPORTED();
2476 } 2602 }
2477 break; 2603 break;
2478 break; 2604 break;
2479 } 2605 }
2480 case TRUNC_L_D: { // Mips32r2 instruction. 2606 case TRUNC_L_D: { // Mips32r2 instruction.
2481 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2607 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2482 double rounded = trunc(fs); 2608 double rounded = trunc(fs);
2483 i64 = static_cast<int64_t>(rounded); 2609 i64 = static_cast<int64_t>(rounded);
2484 if (IsFp64Mode()) { 2610 if (IsFp64Mode()) {
2485 set_fpu_register(fd_reg(), i64); 2611 set_fpu_register(fd_reg(), i64);
2486 if (set_fcsr_round64_error(fs, rounded)) { 2612 if (set_fcsr_round64_error(fs, rounded)) {
2487 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2613 set_fpu_register_invalid_result64(fs, rounded);
2488 } 2614 }
2489 } else { 2615 } else {
2490 UNSUPPORTED(); 2616 UNSUPPORTED();
2491 } 2617 }
2492 break; 2618 break;
2493 } 2619 }
2494 case ROUND_L_D: { // Mips32r2 instruction. 2620 case ROUND_L_D: { // Mips32r2 instruction.
2495 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2621 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2496 double rounded = std::floor(fs + 0.5); 2622 double rounded = std::floor(fs + 0.5);
2497 int64_t result = static_cast<int64_t>(rounded); 2623 int64_t result = static_cast<int64_t>(rounded);
2498 if ((result & 1) != 0 && result - fs == 0.5) { 2624 if ((result & 1) != 0 && result - fs == 0.5) {
2499 // If the number is halfway between two integers, 2625 // If the number is halfway between two integers,
2500 // round to the even one. 2626 // round to the even one.
2501 result--; 2627 result--;
2502 } 2628 }
2503 int64_t i64 = static_cast<int64_t>(result); 2629 int64_t i64 = static_cast<int64_t>(result);
2504 if (IsFp64Mode()) { 2630 if (IsFp64Mode()) {
2505 set_fpu_register(fd_reg(), i64); 2631 set_fpu_register(fd_reg(), i64);
2506 if (set_fcsr_round64_error(fs, rounded)) { 2632 if (set_fcsr_round64_error(fs, rounded)) {
2507 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2633 set_fpu_register_invalid_result64(fs, rounded);
2508 } 2634 }
2509 } else { 2635 } else {
2510 UNSUPPORTED(); 2636 UNSUPPORTED();
2511 } 2637 }
2512 break; 2638 break;
2513 } 2639 }
2514 case FLOOR_L_D: { // Mips32r2 instruction. 2640 case FLOOR_L_D: { // Mips32r2 instruction.
2515 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2641 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2516 double rounded = std::floor(fs); 2642 double rounded = std::floor(fs);
2517 int64_t i64 = static_cast<int64_t>(rounded); 2643 int64_t i64 = static_cast<int64_t>(rounded);
2518 if (IsFp64Mode()) { 2644 if (IsFp64Mode()) {
2519 set_fpu_register(fd_reg(), i64); 2645 set_fpu_register(fd_reg(), i64);
2520 if (set_fcsr_round64_error(fs, rounded)) { 2646 if (set_fcsr_round64_error(fs, rounded)) {
2521 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2647 set_fpu_register_invalid_result64(fs, rounded);
2522 } 2648 }
2523 } else { 2649 } else {
2524 UNSUPPORTED(); 2650 UNSUPPORTED();
2525 } 2651 }
2526 break; 2652 break;
2527 } 2653 }
2528 case CEIL_L_D: { // Mips32r2 instruction. 2654 case CEIL_L_D: { // Mips32r2 instruction.
2529 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2655 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2530 double rounded = std::ceil(fs); 2656 double rounded = std::ceil(fs);
2531 int64_t i64 = static_cast<int64_t>(rounded); 2657 int64_t i64 = static_cast<int64_t>(rounded);
2532 if (IsFp64Mode()) { 2658 if (IsFp64Mode()) {
2533 set_fpu_register(fd_reg(), i64); 2659 set_fpu_register(fd_reg(), i64);
2534 if (set_fcsr_round64_error(fs, rounded)) { 2660 if (set_fcsr_round64_error(fs, rounded)) {
2535 set_fpu_register(fd_reg(), kFPU64InvalidResult); 2661 set_fpu_register_invalid_result64(fs, rounded);
2536 } 2662 }
2537 } else { 2663 } else {
2538 UNSUPPORTED(); 2664 UNSUPPORTED();
2539 } 2665 }
2540 break; 2666 break;
2541 } 2667 }
2542 case CLASS_D: { // Mips32r6 instruction 2668 case CLASS_D: { // Mips32r6 instruction
2543 // Convert double input to uint64_t for easier bit manipulation 2669 // Convert double input to uint64_t for easier bit manipulation
2544 uint64_t classed = bit_cast<uint64_t>(fs); 2670 uint64_t classed = bit_cast<uint64_t>(fs);
2545 2671
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
2928 // MOVF.D 3054 // MOVF.D
2929 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3055 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
2930 } 3056 }
2931 break; 3057 break;
2932 } 3058 }
2933 case TRUNC_W_S: { // Truncate single to word (round towards 0). 3059 case TRUNC_W_S: { // Truncate single to word (round towards 0).
2934 float rounded = trunc(fs); 3060 float rounded = trunc(fs);
2935 int32_t result = static_cast<int32_t>(rounded); 3061 int32_t result = static_cast<int32_t>(rounded);
2936 set_fpu_register_word(fd_reg(), result); 3062 set_fpu_register_word(fd_reg(), result);
2937 if (set_fcsr_round_error(fs, rounded)) { 3063 if (set_fcsr_round_error(fs, rounded)) {
2938 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 3064 set_fpu_register_word_invalid_result(fs, rounded);
2939 } 3065 }
2940 } break; 3066 } break;
2941 case TRUNC_L_S: { // Mips32r2 instruction. 3067 case TRUNC_L_S: { // Mips32r2 instruction.
2942 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3068 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2943 float rounded = trunc(fs); 3069 float rounded = trunc(fs);
2944 int64_t i64 = static_cast<int64_t>(rounded); 3070 int64_t i64 = static_cast<int64_t>(rounded);
2945 if (IsFp64Mode()) { 3071 if (IsFp64Mode()) {
2946 set_fpu_register(fd_reg(), i64); 3072 set_fpu_register(fd_reg(), i64);
2947 if (set_fcsr_round64_error(fs, rounded)) { 3073 if (set_fcsr_round64_error(fs, rounded)) {
2948 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3074 set_fpu_register_invalid_result64(fs, rounded);
2949 } 3075 }
2950 } else { 3076 } else {
2951 UNSUPPORTED(); 3077 UNSUPPORTED();
2952 } 3078 }
2953 break; 3079 break;
2954 } 3080 }
2955 case FLOOR_W_S: // Round double to word towards negative infinity. 3081 case FLOOR_W_S: // Round double to word towards negative infinity.
2956 { 3082 {
2957 float rounded = std::floor(fs); 3083 float rounded = std::floor(fs);
2958 int32_t result = static_cast<int32_t>(rounded); 3084 int32_t result = static_cast<int32_t>(rounded);
2959 set_fpu_register_word(fd_reg(), result); 3085 set_fpu_register_word(fd_reg(), result);
2960 if (set_fcsr_round_error(fs, rounded)) { 3086 if (set_fcsr_round_error(fs, rounded)) {
2961 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 3087 set_fpu_register_word_invalid_result(fs, rounded);
2962 } 3088 }
2963 } break; 3089 } break;
2964 case FLOOR_L_S: { // Mips32r2 instruction. 3090 case FLOOR_L_S: { // Mips32r2 instruction.
2965 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3091 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2966 float rounded = std::floor(fs); 3092 float rounded = std::floor(fs);
2967 int64_t i64 = static_cast<int64_t>(rounded); 3093 int64_t i64 = static_cast<int64_t>(rounded);
2968 if (IsFp64Mode()) { 3094 if (IsFp64Mode()) {
2969 set_fpu_register(fd_reg(), i64); 3095 set_fpu_register(fd_reg(), i64);
2970 if (set_fcsr_round64_error(fs, rounded)) { 3096 if (set_fcsr_round64_error(fs, rounded)) {
2971 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3097 set_fpu_register_invalid_result64(fs, rounded);
2972 } 3098 }
2973 } else { 3099 } else {
2974 UNSUPPORTED(); 3100 UNSUPPORTED();
2975 } 3101 }
2976 break; 3102 break;
2977 } 3103 }
2978 case ROUND_W_S: { 3104 case ROUND_W_S: {
2979 float rounded = std::floor(fs + 0.5); 3105 float rounded = std::floor(fs + 0.5);
2980 int32_t result = static_cast<int32_t>(rounded); 3106 int32_t result = static_cast<int32_t>(rounded);
2981 if ((result & 1) != 0 && result - fs == 0.5) { 3107 if ((result & 1) != 0 && result - fs == 0.5) {
2982 // If the number is halfway between two integers, 3108 // If the number is halfway between two integers,
2983 // round to the even one. 3109 // round to the even one.
2984 result--; 3110 result--;
2985 } 3111 }
2986 set_fpu_register_word(fd_reg(), result); 3112 set_fpu_register_word(fd_reg(), result);
2987 if (set_fcsr_round_error(fs, rounded)) { 3113 if (set_fcsr_round_error(fs, rounded)) {
2988 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 3114 set_fpu_register_word_invalid_result(fs, rounded);
2989 } 3115 }
2990 break; 3116 break;
2991 } 3117 }
2992 case ROUND_L_S: { // Mips32r2 instruction. 3118 case ROUND_L_S: { // Mips32r2 instruction.
2993 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3119 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2994 float rounded = std::floor(fs + 0.5); 3120 float rounded = std::floor(fs + 0.5);
2995 int64_t result = static_cast<int64_t>(rounded); 3121 int64_t result = static_cast<int64_t>(rounded);
2996 if ((result & 1) != 0 && result - fs == 0.5) { 3122 if ((result & 1) != 0 && result - fs == 0.5) {
2997 // If the number is halfway between two integers, 3123 // If the number is halfway between two integers,
2998 // round to the even one. 3124 // round to the even one.
2999 result--; 3125 result--;
3000 } 3126 }
3001 int64_t i64 = static_cast<int64_t>(result); 3127 int64_t i64 = static_cast<int64_t>(result);
3002 if (IsFp64Mode()) { 3128 if (IsFp64Mode()) {
3003 set_fpu_register(fd_reg(), i64); 3129 set_fpu_register(fd_reg(), i64);
3004 if (set_fcsr_round64_error(fs, rounded)) { 3130 if (set_fcsr_round64_error(fs, rounded)) {
3005 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3131 set_fpu_register_invalid_result64(fs, rounded);
3006 } 3132 }
3007 } else { 3133 } else {
3008 UNSUPPORTED(); 3134 UNSUPPORTED();
3009 } 3135 }
3010 break; 3136 break;
3011 } 3137 }
3012 case CEIL_W_S: // Round double to word towards positive infinity. 3138 case CEIL_W_S: // Round double to word towards positive infinity.
3013 { 3139 {
3014 float rounded = std::ceil(fs); 3140 float rounded = std::ceil(fs);
3015 int32_t result = static_cast<int32_t>(rounded); 3141 int32_t result = static_cast<int32_t>(rounded);
3016 set_fpu_register_word(fd_reg(), result); 3142 set_fpu_register_word(fd_reg(), result);
3017 if (set_fcsr_round_error(fs, rounded)) { 3143 if (set_fcsr_round_error(fs, rounded)) {
3018 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 3144 set_fpu_register_word_invalid_result(fs, rounded);
3019 } 3145 }
3020 } break; 3146 } break;
3021 case CEIL_L_S: { // Mips32r2 instruction. 3147 case CEIL_L_S: { // Mips32r2 instruction.
3022 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3148 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3023 float rounded = std::ceil(fs); 3149 float rounded = std::ceil(fs);
3024 int64_t i64 = static_cast<int64_t>(rounded); 3150 int64_t i64 = static_cast<int64_t>(rounded);
3025 if (IsFp64Mode()) { 3151 if (IsFp64Mode()) {
3026 set_fpu_register(fd_reg(), i64); 3152 set_fpu_register(fd_reg(), i64);
3027 if (set_fcsr_round64_error(fs, rounded)) { 3153 if (set_fcsr_round64_error(fs, rounded)) {
3028 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3154 set_fpu_register_invalid_result64(fs, rounded);
3029 } 3155 }
3030 } else { 3156 } else {
3031 UNSUPPORTED(); 3157 UNSUPPORTED();
3032 } 3158 }
3033 break; 3159 break;
3034 } 3160 }
3035 case MIN: 3161 case MIN:
3036 DCHECK(IsMipsArchVariant(kMips32r6)); 3162 DCHECK(IsMipsArchVariant(kMips32r6));
3037 fs = get_fpu_register_float(fs_reg()); 3163 fs = get_fpu_register_float(fs_reg());
3038 if (std::isnan(fs) && std::isnan(ft)) { 3164 if (std::isnan(fs) && std::isnan(ft)) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 set_fpu_register_float(fd_reg(), result); 3226 set_fpu_register_float(fd_reg(), result);
3101 } 3227 }
3102 break; 3228 break;
3103 case CVT_L_S: { 3229 case CVT_L_S: {
3104 if (IsFp64Mode()) { 3230 if (IsFp64Mode()) {
3105 int64_t result; 3231 int64_t result;
3106 float rounded; 3232 float rounded;
3107 round64_according_to_fcsr(fs, rounded, result, fs); 3233 round64_according_to_fcsr(fs, rounded, result, fs);
3108 set_fpu_register(fd_reg(), result); 3234 set_fpu_register(fd_reg(), result);
3109 if (set_fcsr_round64_error(fs, rounded)) { 3235 if (set_fcsr_round64_error(fs, rounded)) {
3110 set_fpu_register(fd_reg(), kFPU64InvalidResult); 3236 set_fpu_register_invalid_result64(fs, rounded);
3111 } 3237 }
3112 } else { 3238 } else {
3113 UNSUPPORTED(); 3239 UNSUPPORTED();
3114 } 3240 }
3115 break; 3241 break;
3116 } 3242 }
3117 case CVT_W_S: { 3243 case CVT_W_S: {
3118 float rounded; 3244 float rounded;
3119 int32_t result; 3245 int32_t result;
3120 round_according_to_fcsr(fs, rounded, result, fs); 3246 round_according_to_fcsr(fs, rounded, result, fs);
3121 set_fpu_register_word(fd_reg(), result); 3247 set_fpu_register_word(fd_reg(), result);
3122 if (set_fcsr_round_error(fs, rounded)) { 3248 if (set_fcsr_round_error(fs, rounded)) {
3123 set_fpu_register_word(fd_reg(), kFPUInvalidResult); 3249 set_fpu_register_word_invalid_result(fs, rounded);
3124 } 3250 }
3125 break; 3251 break;
3126 } 3252 }
3127 default: 3253 default:
3128 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S 3254 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
3129 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. 3255 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
3130 UNREACHABLE(); 3256 UNREACHABLE();
3131 } 3257 }
3132 } 3258 }
3133 3259
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3242 // At the moment only FCSR is supported. 3368 // At the moment only FCSR is supported.
3243 DCHECK(fs_reg() == kFCSRRegister); 3369 DCHECK(fs_reg() == kFCSRRegister);
3244 set_register(rt_reg(), FCSR_); 3370 set_register(rt_reg(), FCSR_);
3245 break; 3371 break;
3246 case MFC1: 3372 case MFC1:
3247 set_register(rt_reg(), get_fpu_register_word(fs_reg())); 3373 set_register(rt_reg(), get_fpu_register_word(fs_reg()));
3248 break; 3374 break;
3249 case MFHC1: 3375 case MFHC1:
3250 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); 3376 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg()));
3251 break; 3377 break;
3252 case CTC1: 3378 case CTC1: {
3253 // At the moment only FCSR is supported. 3379 // At the moment only FCSR is supported.
3254 DCHECK(fs_reg() == kFCSRRegister); 3380 DCHECK(fs_reg() == kFCSRRegister);
3255 FCSR_ = registers_[rt_reg()]; 3381 int32_t reg = registers_[rt_reg()];
3382 if (IsMipsArchVariant(kMips32r6)) {
3383 FCSR_ = reg | kFCSRNaN2008FlagMask;
3384 } else {
3385 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2));
3386 FCSR_ = reg & ~kFCSRNaN2008FlagMask;
3387 }
3256 break; 3388 break;
3389 }
3257 case MTC1: 3390 case MTC1:
3258 // Hardware writes upper 32-bits to zero on mtc1. 3391 // Hardware writes upper 32-bits to zero on mtc1.
3259 set_fpu_register_hi_word(fs_reg(), 0); 3392 set_fpu_register_hi_word(fs_reg(), 0);
3260 set_fpu_register_word(fs_reg(), registers_[rt_reg()]); 3393 set_fpu_register_word(fs_reg(), registers_[rt_reg()]);
3261 break; 3394 break;
3262 case MTHC1: 3395 case MTHC1:
3263 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]); 3396 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]);
3264 break; 3397 break;
3265 case S: { 3398 case S: {
3266 DecodeTypeRegisterSRsType(); 3399 DecodeTypeRegisterSRsType();
(...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after
4442 4575
4443 4576
4444 #undef UNSUPPORTED 4577 #undef UNSUPPORTED
4445 4578
4446 } // namespace internal 4579 } // namespace internal
4447 } // namespace v8 4580 } // namespace v8
4448 4581
4449 #endif // USE_SIMULATOR 4582 #endif // USE_SIMULATOR
4450 4583
4451 #endif // V8_TARGET_ARCH_MIPS 4584 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698