Chromium Code Reviews| 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 |