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 #if V8_TARGET_ARCH_MIPS | 10 #if V8_TARGET_ARCH_MIPS |
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |