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

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

Issue 1668143002: MIPS: Fix FPU min, max, mina, maxa in simulator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months 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
« no previous file with comments | « src/mips/simulator-mips.h ('k') | src/mips64/simulator-mips64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2340 } 2340 }
2341 } 2341 }
2342 } 2342 }
2343 2343
2344 2344
2345 void Simulator::SignalException(Exception e) { 2345 void Simulator::SignalException(Exception e) {
2346 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", 2346 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.",
2347 static_cast<int>(e)); 2347 static_cast<int>(e));
2348 } 2348 }
2349 2349
2350 template <typename T>
2351 T FPAbs(T a);
2352
2353 template <>
2354 double FPAbs<double>(double a) {
2355 return fabs(a);
2356 }
2357
2358 template <>
2359 float FPAbs<float>(float a) {
2360 return fabsf(a);
2361 }
2362
2363 template <typename T>
2364 bool Simulator::FPUProcessNaNsAndZeros(T a, T b, IsMin min, T& result) {
2365 if (std::isnan(a) && std::isnan(b)) {
2366 result = a;
2367 } else if (std::isnan(a)) {
2368 result = b;
2369 } else if (std::isnan(b)) {
2370 result = a;
2371 } else if (b == a) {
2372 // Handle -0.0 == 0.0 case.
2373 // std::signbit() returns int 0 or 1 so substracting IsMin::kMax negates the
2374 // result.
2375 result = std::signbit(b) - static_cast<int>(min) ? b : a;
2376 } else {
2377 return false;
2378 }
2379 return true;
2380 }
2381
2382 template <typename T>
2383 T Simulator::FPUMin(T a, T b) {
2384 T result;
2385 if (FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
2386 return result;
2387 } else {
2388 return b < a ? b : a;
2389 }
2390 }
2391
2392 template <typename T>
2393 T Simulator::FPUMax(T a, T b) {
2394 T result;
2395 if (FPUProcessNaNsAndZeros(a, b, IsMin::kMax, result)) {
2396 return result;
2397 } else {
2398 return b > a ? b : a;
2399 }
2400 }
2401
2402 template <typename T>
2403 T Simulator::FPUMinA(T a, T b) {
2404 T result;
2405 if (!FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
2406 if (FPAbs(a) < FPAbs(b)) {
2407 result = a;
2408 } else if (FPAbs(b) < FPAbs(a)) {
2409 result = b;
2410 } else {
2411 result = a < b ? a : b;
2412 }
2413 }
2414 return result;
2415 }
2416
2417 template <typename T>
2418 T Simulator::FPUMaxA(T a, T b) {
2419 T result;
2420 if (!FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
2421 if (FPAbs(a) > FPAbs(b)) {
2422 result = a;
2423 } else if (FPAbs(b) > FPAbs(a)) {
2424 result = b;
2425 } else {
2426 result = a > b ? a : b;
2427 }
2428 }
2429 return result;
2430 }
2431
2432 // Handle execution based on instruction types.
2350 2433
2351 void Simulator::DecodeTypeRegisterDRsType() { 2434 void Simulator::DecodeTypeRegisterDRsType() {
2352 double ft, fs, fd; 2435 double ft, fs, fd;
2353 uint32_t cc, fcsr_cc; 2436 uint32_t cc, fcsr_cc;
2354 int64_t i64; 2437 int64_t i64;
2355 fs = get_fpu_register_double(fs_reg()); 2438 fs = get_fpu_register_double(fs_reg());
2356 ft = (get_instr()->FunctionFieldRaw() != MOVF) 2439 ft = (get_instr()->FunctionFieldRaw() != MOVF)
2357 ? get_fpu_register_double(ft_reg()) 2440 ? get_fpu_register_double(ft_reg())
2358 : 0.0; 2441 : 0.0;
2359 fd = get_fpu_register_double(fd_reg()); 2442 fd = get_fpu_register_double(fd_reg());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2435 // MOVT.D 2518 // MOVT.D
2436 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2519 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2437 } else { 2520 } else {
2438 // MOVF.D 2521 // MOVF.D
2439 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2522 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2440 } 2523 }
2441 break; 2524 break;
2442 } 2525 }
2443 case MIN: 2526 case MIN:
2444 DCHECK(IsMipsArchVariant(kMips32r6)); 2527 DCHECK(IsMipsArchVariant(kMips32r6));
2445 fs = get_fpu_register_double(fs_reg()); 2528 set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
2446 if (std::isnan(fs) && std::isnan(ft)) { 2529 break;
2447 set_fpu_register_double(fd_reg(), fs); 2530 case MAX:
2448 } else if (std::isnan(fs) && !std::isnan(ft)) { 2531 DCHECK(IsMipsArchVariant(kMips32r6));
2449 set_fpu_register_double(fd_reg(), ft); 2532 set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
2450 } else if (!std::isnan(fs) && std::isnan(ft)) {
2451 set_fpu_register_double(fd_reg(), fs);
2452 } else {
2453 set_fpu_register_double(fd_reg(), (fs >= ft) ? ft : fs);
2454 }
2455 break; 2533 break;
2456 case MINA: 2534 case MINA:
2457 DCHECK(IsMipsArchVariant(kMips32r6)); 2535 DCHECK(IsMipsArchVariant(kMips32r6));
2458 fs = get_fpu_register_double(fs_reg()); 2536 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
2459 if (std::isnan(fs) && std::isnan(ft)) {
2460 set_fpu_register_double(fd_reg(), fs);
2461 } else if (std::isnan(fs) && !std::isnan(ft)) {
2462 set_fpu_register_double(fd_reg(), ft);
2463 } else if (!std::isnan(fs) && std::isnan(ft)) {
2464 set_fpu_register_double(fd_reg(), fs);
2465 } else {
2466 double result;
2467 if (fabs(fs) > fabs(ft)) {
2468 result = ft;
2469 } else if (fabs(fs) < fabs(ft)) {
2470 result = fs;
2471 } else {
2472 result = (fs < ft ? fs : ft);
2473 }
2474 set_fpu_register_double(fd_reg(), result);
2475 }
2476 break; 2537 break;
2477 case MAXA: 2538 case MAXA:
2478 DCHECK(IsMipsArchVariant(kMips32r6)); 2539 DCHECK(IsMipsArchVariant(kMips32r6));
2479 fs = get_fpu_register_double(fs_reg()); 2540 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
2480 if (std::isnan(fs) && std::isnan(ft)) {
2481 set_fpu_register_double(fd_reg(), fs);
2482 } else if (std::isnan(fs) && !std::isnan(ft)) {
2483 set_fpu_register_double(fd_reg(), ft);
2484 } else if (!std::isnan(fs) && std::isnan(ft)) {
2485 set_fpu_register_double(fd_reg(), fs);
2486 } else {
2487 double result;
2488 if (fabs(fs) < fabs(ft)) {
2489 result = ft;
2490 } else if (fabs(fs) > fabs(ft)) {
2491 result = fs;
2492 } else {
2493 result = (fs > ft ? fs : ft);
2494 }
2495 set_fpu_register_double(fd_reg(), result);
2496 }
2497 break;
2498 case MAX:
2499 DCHECK(IsMipsArchVariant(kMips32r6));
2500 fs = get_fpu_register_double(fs_reg());
2501 if (std::isnan(fs) && std::isnan(ft)) {
2502 set_fpu_register_double(fd_reg(), fs);
2503 } else if (std::isnan(fs) && !std::isnan(ft)) {
2504 set_fpu_register_double(fd_reg(), ft);
2505 } else if (!std::isnan(fs) && std::isnan(ft)) {
2506 set_fpu_register_double(fd_reg(), fs);
2507 } else {
2508 set_fpu_register_double(fd_reg(), (fs <= ft) ? ft : fs);
2509 }
2510 break;
2511 break; 2541 break;
2512 case ADD_D: 2542 case ADD_D:
2513 set_fpu_register_double(fd_reg(), fs + ft); 2543 set_fpu_register_double(fd_reg(), fs + ft);
2514 break; 2544 break;
2515 case SUB_D: 2545 case SUB_D:
2516 set_fpu_register_double(fd_reg(), fs - ft); 2546 set_fpu_register_double(fd_reg(), fs - ft);
2517 break; 2547 break;
2518 case MUL_D: 2548 case MUL_D:
2519 set_fpu_register_double(fd_reg(), fs * ft); 2549 set_fpu_register_double(fd_reg(), fs * ft);
2520 break; 2550 break;
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
3186 if (set_fcsr_round64_error(fs, rounded)) { 3216 if (set_fcsr_round64_error(fs, rounded)) {
3187 set_fpu_register_invalid_result64(fs, rounded); 3217 set_fpu_register_invalid_result64(fs, rounded);
3188 } 3218 }
3189 } else { 3219 } else {
3190 UNSUPPORTED(); 3220 UNSUPPORTED();
3191 } 3221 }
3192 break; 3222 break;
3193 } 3223 }
3194 case MIN: 3224 case MIN:
3195 DCHECK(IsMipsArchVariant(kMips32r6)); 3225 DCHECK(IsMipsArchVariant(kMips32r6));
3196 fs = get_fpu_register_float(fs_reg()); 3226 set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
3197 if (std::isnan(fs) && std::isnan(ft)) {
3198 set_fpu_register_float(fd_reg(), fs);
3199 } else if (std::isnan(fs) && !std::isnan(ft)) {
3200 set_fpu_register_float(fd_reg(), ft);
3201 } else if (!std::isnan(fs) && std::isnan(ft)) {
3202 set_fpu_register_float(fd_reg(), fs);
3203 } else {
3204 set_fpu_register_float(fd_reg(), (fs >= ft) ? ft : fs);
3205 }
3206 break; 3227 break;
3207 case MAX: 3228 case MAX:
3208 DCHECK(IsMipsArchVariant(kMips32r6)); 3229 DCHECK(IsMipsArchVariant(kMips32r6));
3209 fs = get_fpu_register_float(fs_reg()); 3230 set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
3210 if (std::isnan(fs) && std::isnan(ft)) {
3211 set_fpu_register_float(fd_reg(), fs);
3212 } else if (std::isnan(fs) && !std::isnan(ft)) {
3213 set_fpu_register_float(fd_reg(), ft);
3214 } else if (!std::isnan(fs) && std::isnan(ft)) {
3215 set_fpu_register_float(fd_reg(), fs);
3216 } else {
3217 set_fpu_register_float(fd_reg(), (fs <= ft) ? ft : fs);
3218 }
3219 break; 3231 break;
3220 case MINA: 3232 case MINA:
3221 DCHECK(IsMipsArchVariant(kMips32r6)); 3233 DCHECK(IsMipsArchVariant(kMips32r6));
3222 fs = get_fpu_register_float(fs_reg()); 3234 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
3223 if (std::isnan(fs) && std::isnan(ft)) {
3224 set_fpu_register_float(fd_reg(), fs);
3225 } else if (std::isnan(fs) && !std::isnan(ft)) {
3226 set_fpu_register_float(fd_reg(), ft);
3227 } else if (!std::isnan(fs) && std::isnan(ft)) {
3228 set_fpu_register_float(fd_reg(), fs);
3229 } else {
3230 float result;
3231 if (fabs(fs) > fabs(ft)) {
3232 result = ft;
3233 } else if (fabs(fs) < fabs(ft)) {
3234 result = fs;
3235 } else {
3236 result = (fs < ft ? fs : ft);
3237 }
3238 set_fpu_register_float(fd_reg(), result);
3239 }
3240 break; 3235 break;
3241 case MAXA: 3236 case MAXA:
3242 DCHECK(IsMipsArchVariant(kMips32r6)); 3237 DCHECK(IsMipsArchVariant(kMips32r6));
3243 fs = get_fpu_register_float(fs_reg()); 3238 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
3244 if (std::isnan(fs) && std::isnan(ft)) {
3245 set_fpu_register_float(fd_reg(), fs);
3246 } else if (std::isnan(fs) && !std::isnan(ft)) {
3247 set_fpu_register_float(fd_reg(), ft);
3248 } else if (!std::isnan(fs) && std::isnan(ft)) {
3249 set_fpu_register_float(fd_reg(), fs);
3250 } else {
3251 float result;
3252 if (fabs(fs) < fabs(ft)) {
3253 result = ft;
3254 } else if (fabs(fs) > fabs(ft)) {
3255 result = fs;
3256 } else {
3257 result = (fs > ft ? fs : ft);
3258 }
3259 set_fpu_register_float(fd_reg(), result);
3260 }
3261 break; 3239 break;
3262 case CVT_L_S: { 3240 case CVT_L_S: {
3263 if (IsFp64Mode()) { 3241 if (IsFp64Mode()) {
3264 int64_t result; 3242 int64_t result;
3265 float rounded; 3243 float rounded;
3266 round64_according_to_fcsr(fs, rounded, result, fs); 3244 round64_according_to_fcsr(fs, rounded, result, fs);
3267 set_fpu_register(fd_reg(), result); 3245 set_fpu_register(fd_reg(), result);
3268 if (set_fcsr_round64_error(fs, rounded)) { 3246 if (set_fcsr_round64_error(fs, rounded)) {
3269 set_fpu_register_invalid_result64(fs, rounded); 3247 set_fpu_register_invalid_result64(fs, rounded);
3270 } 3248 }
(...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
4615 4593
4616 4594
4617 #undef UNSUPPORTED 4595 #undef UNSUPPORTED
4618 4596
4619 } // namespace internal 4597 } // namespace internal
4620 } // namespace v8 4598 } // namespace v8
4621 4599
4622 #endif // USE_SIMULATOR 4600 #endif // USE_SIMULATOR
4623 4601
4624 #endif // V8_TARGET_ARCH_MIPS 4602 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.h ('k') | src/mips64/simulator-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698