OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3277 #ifdef OBJECT_PRINT | 3277 #ifdef OBJECT_PRINT |
3278 ::printf("f(%d) = ", i); | 3278 ::printf("f(%d) = ", i); |
3279 result->Print(std::cout); | 3279 result->Print(std::cout); |
3280 ::printf("\n"); | 3280 ::printf("\n"); |
3281 #endif | 3281 #endif |
3282 CHECK(values[i].is_identical_to(result)); | 3282 CHECK(values[i].is_identical_to(result)); |
3283 } | 3283 } |
3284 } | 3284 } |
3285 | 3285 |
3286 | 3286 |
| 3287 TEST(BITSWAP) { |
| 3288 // Test BITSWAP |
| 3289 if (kArchVariant == kMips64r6) { |
| 3290 CcTest::InitializeVM(); |
| 3291 Isolate* isolate = CcTest::i_isolate(); |
| 3292 HandleScope scope(isolate); |
| 3293 |
| 3294 typedef struct { |
| 3295 int64_t r1; |
| 3296 int64_t r2; |
| 3297 int64_t r3; |
| 3298 int64_t r4; |
| 3299 int64_t r5; |
| 3300 int64_t r6; |
| 3301 } T; |
| 3302 T t; |
| 3303 |
| 3304 Assembler assm(isolate, NULL, 0); |
| 3305 |
| 3306 __ ld(a4, MemOperand(a0, OFFSET_OF(T, r1))); |
| 3307 __ nop(); |
| 3308 __ bitswap(a6, a4); |
| 3309 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r1))); |
| 3310 |
| 3311 __ ld(a4, MemOperand(a0, OFFSET_OF(T, r2))); |
| 3312 __ nop(); |
| 3313 __ bitswap(a6, a4); |
| 3314 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r2))); |
| 3315 |
| 3316 __ ld(a4, MemOperand(a0, OFFSET_OF(T, r3))); |
| 3317 __ nop(); |
| 3318 __ bitswap(a6, a4); |
| 3319 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r3))); |
| 3320 |
| 3321 __ ld(a4, MemOperand(a0, OFFSET_OF(T, r4))); |
| 3322 __ nop(); |
| 3323 __ bitswap(a6, a4); |
| 3324 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r4))); |
| 3325 |
| 3326 __ ld(a4, MemOperand(a0, OFFSET_OF(T, r5))); |
| 3327 __ nop(); |
| 3328 __ dbitswap(a6, a4); |
| 3329 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r5))); |
| 3330 |
| 3331 __ ld(a4, MemOperand(a0, OFFSET_OF(T, r6))); |
| 3332 __ nop(); |
| 3333 __ dbitswap(a6, a4); |
| 3334 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r6))); |
| 3335 |
| 3336 __ jr(ra); |
| 3337 __ nop(); |
| 3338 |
| 3339 CodeDesc desc; |
| 3340 assm.GetCode(&desc); |
| 3341 Handle<Code> code = isolate->factory()->NewCode( |
| 3342 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 3343 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 3344 t.r1 = 0x00102100781A15C3; |
| 3345 t.r2 = 0x001021008B71FCDE; |
| 3346 t.r3 = 0xFF8017FF781A15C3; |
| 3347 t.r4 = 0xFF8017FF8B71FCDE; |
| 3348 t.r5 = 0x10C021098B71FCDE; |
| 3349 t.r6 = 0xFB8017FF781A15C3; |
| 3350 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
| 3351 USE(dummy); |
| 3352 |
| 3353 CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r1); |
| 3354 CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFD18E3F7BL), t.r2); |
| 3355 CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r3); |
| 3356 CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFD18E3F7BL), t.r4); |
| 3357 CHECK_EQ(static_cast<int64_t>(0x08038490D18E3F7BL), t.r5); |
| 3358 CHECK_EQ(static_cast<int64_t>(0xDF01E8FF1E58A8C3L), t.r6); |
| 3359 } |
| 3360 } |
| 3361 |
| 3362 |
| 3363 TEST(class_fmt) { |
| 3364 if (kArchVariant == kMips64r6) { |
| 3365 // Test CLASS.fmt instruction. |
| 3366 CcTest::InitializeVM(); |
| 3367 Isolate* isolate = CcTest::i_isolate(); |
| 3368 HandleScope scope(isolate); |
| 3369 |
| 3370 typedef struct { |
| 3371 double dSignalingNan; |
| 3372 double dQuietNan; |
| 3373 double dNegInf; |
| 3374 double dNegNorm; |
| 3375 double dNegSubnorm; |
| 3376 double dNegZero; |
| 3377 double dPosInf; |
| 3378 double dPosNorm; |
| 3379 double dPosSubnorm; |
| 3380 double dPosZero; |
| 3381 float fSignalingNan; |
| 3382 float fQuietNan; |
| 3383 float fNegInf; |
| 3384 float fNegNorm; |
| 3385 float fNegSubnorm; |
| 3386 float fNegZero; |
| 3387 float fPosInf; |
| 3388 float fPosNorm; |
| 3389 float fPosSubnorm; |
| 3390 float fPosZero; } T; |
| 3391 T t; |
| 3392 |
| 3393 // Create a function that accepts &t, and loads, manipulates, and stores |
| 3394 // the doubles t.a ... t.f. |
| 3395 MacroAssembler assm(isolate, NULL, 0); |
| 3396 |
| 3397 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dSignalingNan))); |
| 3398 __ class_d(f6, f4); |
| 3399 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dSignalingNan))); |
| 3400 |
| 3401 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dQuietNan))); |
| 3402 __ class_d(f6, f4); |
| 3403 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dQuietNan))); |
| 3404 |
| 3405 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dNegInf))); |
| 3406 __ class_d(f6, f4); |
| 3407 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dNegInf))); |
| 3408 |
| 3409 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dNegNorm))); |
| 3410 __ class_d(f6, f4); |
| 3411 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dNegNorm))); |
| 3412 |
| 3413 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dNegSubnorm))); |
| 3414 __ class_d(f6, f4); |
| 3415 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dNegSubnorm))); |
| 3416 |
| 3417 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dNegZero))); |
| 3418 __ class_d(f6, f4); |
| 3419 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dNegZero))); |
| 3420 |
| 3421 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dPosInf))); |
| 3422 __ class_d(f6, f4); |
| 3423 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dPosInf))); |
| 3424 |
| 3425 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dPosNorm))); |
| 3426 __ class_d(f6, f4); |
| 3427 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dPosNorm))); |
| 3428 |
| 3429 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dPosSubnorm))); |
| 3430 __ class_d(f6, f4); |
| 3431 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dPosSubnorm))); |
| 3432 |
| 3433 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, dPosZero))); |
| 3434 __ class_d(f6, f4); |
| 3435 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, dPosZero))); |
| 3436 |
| 3437 // Testing instruction CLASS.S |
| 3438 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fSignalingNan))); |
| 3439 __ class_s(f6, f4); |
| 3440 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fSignalingNan))); |
| 3441 |
| 3442 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fQuietNan))); |
| 3443 __ class_s(f6, f4); |
| 3444 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fQuietNan))); |
| 3445 |
| 3446 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fNegInf))); |
| 3447 __ class_s(f6, f4); |
| 3448 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fNegInf))); |
| 3449 |
| 3450 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fNegNorm))); |
| 3451 __ class_s(f6, f4); |
| 3452 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fNegNorm))); |
| 3453 |
| 3454 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fNegSubnorm))); |
| 3455 __ class_s(f6, f4); |
| 3456 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fNegSubnorm))); |
| 3457 |
| 3458 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fNegZero))); |
| 3459 __ class_s(f6, f4); |
| 3460 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fNegZero))); |
| 3461 |
| 3462 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fPosInf))); |
| 3463 __ class_s(f6, f4); |
| 3464 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fPosInf))); |
| 3465 |
| 3466 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fPosNorm))); |
| 3467 __ class_s(f6, f4); |
| 3468 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fPosNorm))); |
| 3469 |
| 3470 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fPosSubnorm))); |
| 3471 __ class_s(f6, f4); |
| 3472 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fPosSubnorm))); |
| 3473 |
| 3474 __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fPosZero))); |
| 3475 __ class_s(f6, f4); |
| 3476 __ swc1(f6, MemOperand(a0, OFFSET_OF(T, fPosZero))); |
| 3477 |
| 3478 __ jr(ra); |
| 3479 __ nop(); |
| 3480 |
| 3481 CodeDesc desc; |
| 3482 assm.GetCode(&desc); |
| 3483 Handle<Code> code = isolate->factory()->NewCode( |
| 3484 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 3485 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 3486 |
| 3487 // Double test values. |
| 3488 t.dSignalingNan = std::numeric_limits<double>::signaling_NaN(); |
| 3489 t.dQuietNan = std::numeric_limits<double>::quiet_NaN(); |
| 3490 t.dNegInf = -1.0 / 0.0; |
| 3491 t.dNegNorm = -5.0; |
| 3492 t.dNegSubnorm = -DBL_MIN / 2.0; |
| 3493 t.dNegZero = -0.0; |
| 3494 t.dPosInf = 2.0 / 0.0; |
| 3495 t.dPosNorm = 275.35; |
| 3496 t.dPosSubnorm = DBL_MIN / 2.0; |
| 3497 t.dPosZero = +0.0; |
| 3498 // Float test values |
| 3499 |
| 3500 t.fSignalingNan = std::numeric_limits<float>::signaling_NaN(); |
| 3501 t.fQuietNan = std::numeric_limits<float>::quiet_NaN(); |
| 3502 t.fNegInf = -0.5/0.0; |
| 3503 t.fNegNorm = -FLT_MIN; |
| 3504 t.fNegSubnorm = -FLT_MIN / 1.5; |
| 3505 t.fNegZero = -0.0; |
| 3506 t.fPosInf = 100000.0 / 0.0; |
| 3507 t.fPosNorm = FLT_MAX; |
| 3508 t.fPosSubnorm = FLT_MIN / 20.0; |
| 3509 t.fPosZero = +0.0; |
| 3510 |
| 3511 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
| 3512 USE(dummy); |
| 3513 // Expected double results. |
| 3514 CHECK_EQ(bit_cast<uint64_t>(t.dNegInf), 0x004); |
| 3515 CHECK_EQ(bit_cast<uint64_t>(t.dNegNorm), 0x008); |
| 3516 CHECK_EQ(bit_cast<uint64_t>(t.dNegSubnorm), 0x010); |
| 3517 CHECK_EQ(bit_cast<uint64_t>(t.dNegZero), 0x020); |
| 3518 CHECK_EQ(bit_cast<uint64_t>(t.dPosInf), 0x040); |
| 3519 CHECK_EQ(bit_cast<uint64_t>(t.dPosNorm), 0x080); |
| 3520 CHECK_EQ(bit_cast<uint64_t>(t.dPosSubnorm), 0x100); |
| 3521 CHECK_EQ(bit_cast<uint64_t>(t.dPosZero), 0x200); |
| 3522 |
| 3523 // Expected float results. |
| 3524 CHECK_EQ(bit_cast<uint32_t>(t.fNegInf), 0x004); |
| 3525 CHECK_EQ(bit_cast<uint32_t>(t.fNegNorm), 0x008); |
| 3526 CHECK_EQ(bit_cast<uint32_t>(t.fNegSubnorm), 0x010); |
| 3527 CHECK_EQ(bit_cast<uint32_t>(t.fNegZero), 0x020); |
| 3528 CHECK_EQ(bit_cast<uint32_t>(t.fPosInf), 0x040); |
| 3529 CHECK_EQ(bit_cast<uint32_t>(t.fPosNorm), 0x080); |
| 3530 CHECK_EQ(bit_cast<uint32_t>(t.fPosSubnorm), 0x100); |
| 3531 CHECK_EQ(bit_cast<uint32_t>(t.fPosZero), 0x200); |
| 3532 } |
| 3533 } |
| 3534 |
| 3535 |
| 3536 TEST(ABS) { |
| 3537 CcTest::InitializeVM(); |
| 3538 Isolate* isolate = CcTest::i_isolate(); |
| 3539 HandleScope scope(isolate); |
| 3540 MacroAssembler assm(isolate, NULL, 0); |
| 3541 |
| 3542 typedef struct test_float { |
| 3543 int64_t fir; |
| 3544 double a; |
| 3545 float b; |
| 3546 double fcsr; |
| 3547 } TestFloat; |
| 3548 |
| 3549 TestFloat test; |
| 3550 |
| 3551 // Save FIR. |
| 3552 __ cfc1(a1, FCSR); |
| 3553 __ sd(a1, MemOperand(a0, OFFSET_OF(TestFloat, fcsr))); |
| 3554 // Disable FPU exceptions. |
| 3555 __ ctc1(zero_reg, FCSR); |
| 3556 |
| 3557 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a))); |
| 3558 __ abs_d(f10, f4); |
| 3559 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, a))); |
| 3560 |
| 3561 __ lwc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, b))); |
| 3562 __ abs_s(f10, f4); |
| 3563 __ swc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, b))); |
| 3564 |
| 3565 // Restore FCSR. |
| 3566 __ ctc1(a1, FCSR); |
| 3567 |
| 3568 __ jr(ra); |
| 3569 __ nop(); |
| 3570 |
| 3571 CodeDesc desc; |
| 3572 assm.GetCode(&desc); |
| 3573 Handle<Code> code = isolate->factory()->NewCode( |
| 3574 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 3575 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 3576 test.a = -2.0; |
| 3577 test.b = -2.0; |
| 3578 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3579 CHECK_EQ(test.a, 2.0); |
| 3580 CHECK_EQ(test.b, 2.0); |
| 3581 |
| 3582 test.a = 2.0; |
| 3583 test.b = 2.0; |
| 3584 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3585 CHECK_EQ(test.a, 2.0); |
| 3586 CHECK_EQ(test.b, 2.0); |
| 3587 |
| 3588 // Testing biggest positive number |
| 3589 test.a = std::numeric_limits<double>::max(); |
| 3590 test.b = std::numeric_limits<float>::max(); |
| 3591 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3592 CHECK_EQ(test.a, std::numeric_limits<double>::max()); |
| 3593 CHECK_EQ(test.b, std::numeric_limits<float>::max()); |
| 3594 |
| 3595 // Testing smallest negative number |
| 3596 test.a = -std::numeric_limits<double>::lowest(); |
| 3597 test.b = -std::numeric_limits<float>::lowest(); |
| 3598 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3599 CHECK_EQ(test.a, std::numeric_limits<double>::max()); |
| 3600 CHECK_EQ(test.b, std::numeric_limits<float>::max()); |
| 3601 |
| 3602 // Testing smallest positive number |
| 3603 test.a = -std::numeric_limits<double>::min(); |
| 3604 test.b = -std::numeric_limits<float>::min(); |
| 3605 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3606 CHECK_EQ(test.a, std::numeric_limits<double>::min()); |
| 3607 CHECK_EQ(test.b, std::numeric_limits<float>::min()); |
| 3608 |
| 3609 // Testing infinity |
| 3610 test.a = -std::numeric_limits<double>::max() |
| 3611 / std::numeric_limits<double>::min(); |
| 3612 test.b = -std::numeric_limits<float>::max() |
| 3613 / std::numeric_limits<float>::min(); |
| 3614 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3615 CHECK_EQ(test.a, std::numeric_limits<double>::max() |
| 3616 / std::numeric_limits<double>::min()); |
| 3617 CHECK_EQ(test.b, std::numeric_limits<float>::max() |
| 3618 / std::numeric_limits<float>::min()); |
| 3619 |
| 3620 test.a = std::numeric_limits<double>::quiet_NaN(); |
| 3621 test.b = std::numeric_limits<float>::quiet_NaN(); |
| 3622 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3623 CHECK_EQ(std::isnan(test.a), true); |
| 3624 CHECK_EQ(std::isnan(test.b), true); |
| 3625 |
| 3626 test.a = std::numeric_limits<double>::signaling_NaN(); |
| 3627 test.b = std::numeric_limits<float>::signaling_NaN(); |
| 3628 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3629 CHECK_EQ(std::isnan(test.a), true); |
| 3630 CHECK_EQ(std::isnan(test.b), true); |
| 3631 } |
| 3632 |
| 3633 |
| 3634 TEST(ADD_FMT) { |
| 3635 CcTest::InitializeVM(); |
| 3636 Isolate* isolate = CcTest::i_isolate(); |
| 3637 HandleScope scope(isolate); |
| 3638 MacroAssembler assm(isolate, NULL, 0); |
| 3639 |
| 3640 typedef struct test_float { |
| 3641 double a; |
| 3642 double b; |
| 3643 double c; |
| 3644 float fa; |
| 3645 float fb; |
| 3646 float fc; |
| 3647 } TestFloat; |
| 3648 |
| 3649 TestFloat test; |
| 3650 |
| 3651 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a))); |
| 3652 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b))); |
| 3653 __ add_d(f10, f8, f4); |
| 3654 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c))); |
| 3655 |
| 3656 __ lwc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, fa))); |
| 3657 __ lwc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, fb))); |
| 3658 __ add_s(f10, f8, f4); |
| 3659 __ swc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, fc))); |
| 3660 |
| 3661 __ jr(ra); |
| 3662 __ nop(); |
| 3663 |
| 3664 CodeDesc desc; |
| 3665 assm.GetCode(&desc); |
| 3666 Handle<Code> code = isolate->factory()->NewCode( |
| 3667 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 3668 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 3669 test.a = 2.0; |
| 3670 test.b = 3.0; |
| 3671 test.fa = 2.0; |
| 3672 test.fb = 3.0; |
| 3673 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3674 CHECK_EQ(test.c, 5.0); |
| 3675 CHECK_EQ(test.fc, 5.0); |
| 3676 |
| 3677 test.a = std::numeric_limits<double>::max(); |
| 3678 test.b = std::numeric_limits<double>::lowest(); |
| 3679 test.fa = std::numeric_limits<float>::max(); |
| 3680 test.fb = std::numeric_limits<float>::lowest(); |
| 3681 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3682 CHECK_EQ(test.c, 0.0); |
| 3683 CHECK_EQ(test.fc, 0.0); |
| 3684 |
| 3685 test.a = std::numeric_limits<double>::max(); |
| 3686 test.b = std::numeric_limits<double>::max(); |
| 3687 test.fa = std::numeric_limits<float>::max(); |
| 3688 test.fb = std::numeric_limits<float>::max(); |
| 3689 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3690 CHECK_EQ(std::isfinite(test.c), false); |
| 3691 CHECK_EQ(std::isfinite(test.fc), false); |
| 3692 |
| 3693 test.a = 5.0; |
| 3694 test.b = std::numeric_limits<double>::signaling_NaN(); |
| 3695 test.fa = 5.0; |
| 3696 test.fb = std::numeric_limits<float>::signaling_NaN(); |
| 3697 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3698 CHECK_EQ(std::isnan(test.c), true); |
| 3699 CHECK_EQ(std::isnan(test.fc), true); |
| 3700 } |
| 3701 |
| 3702 |
| 3703 TEST(C_COND_FMT) { |
| 3704 if (kArchVariant == kMips64r2) { |
| 3705 CcTest::InitializeVM(); |
| 3706 Isolate* isolate = CcTest::i_isolate(); |
| 3707 HandleScope scope(isolate); |
| 3708 MacroAssembler assm(isolate, NULL, 0); |
| 3709 |
| 3710 typedef struct test_float { |
| 3711 double dOp1; |
| 3712 double dOp2; |
| 3713 uint32_t dF; |
| 3714 uint32_t dUn; |
| 3715 uint32_t dEq; |
| 3716 uint32_t dUeq; |
| 3717 uint32_t dOlt; |
| 3718 uint32_t dUlt; |
| 3719 uint32_t dOle; |
| 3720 uint32_t dUle; |
| 3721 float fOp1; |
| 3722 float fOp2; |
| 3723 uint32_t fF; |
| 3724 uint32_t fUn; |
| 3725 uint32_t fEq; |
| 3726 uint32_t fUeq; |
| 3727 uint32_t fOlt; |
| 3728 uint32_t fUlt; |
| 3729 uint32_t fOle; |
| 3730 uint32_t fUle; |
| 3731 } TestFloat; |
| 3732 |
| 3733 TestFloat test; |
| 3734 |
| 3735 __ li(t1, 1); |
| 3736 |
| 3737 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, dOp1))); |
| 3738 __ ldc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, dOp2))); |
| 3739 |
| 3740 __ lwc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, fOp1))); |
| 3741 __ lwc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, fOp2))); |
| 3742 |
| 3743 __ mov(t2, zero_reg); |
| 3744 __ mov(t3, zero_reg); |
| 3745 __ c_d(F, f4, f6, 0); |
| 3746 __ c_s(F, f14, f16, 2); |
| 3747 __ movt(t2, t1, 0); |
| 3748 __ movt(t3, t1, 2); |
| 3749 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dF)) ); |
| 3750 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fF)) ); |
| 3751 |
| 3752 __ mov(t2, zero_reg); |
| 3753 __ mov(t3, zero_reg); |
| 3754 __ c_d(UN, f4, f6, 2); |
| 3755 __ c_s(UN, f14, f16, 4); |
| 3756 __ movt(t2, t1, 2); |
| 3757 __ movt(t3, t1, 4); |
| 3758 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dUn)) ); |
| 3759 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fUn)) ); |
| 3760 |
| 3761 __ mov(t2, zero_reg); |
| 3762 __ mov(t3, zero_reg); |
| 3763 __ c_d(EQ, f4, f6, 4); |
| 3764 __ c_s(EQ, f14, f16, 6); |
| 3765 __ movt(t2, t1, 4); |
| 3766 __ movt(t3, t1, 6); |
| 3767 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dEq)) ); |
| 3768 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fEq)) ); |
| 3769 |
| 3770 __ mov(t2, zero_reg); |
| 3771 __ mov(t3, zero_reg); |
| 3772 __ c_d(UEQ, f4, f6, 6); |
| 3773 __ c_s(UEQ, f14, f16, 0); |
| 3774 __ movt(t2, t1, 6); |
| 3775 __ movt(t3, t1, 0); |
| 3776 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dUeq)) ); |
| 3777 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fUeq)) ); |
| 3778 |
| 3779 __ mov(t2, zero_reg); |
| 3780 __ mov(t3, zero_reg); |
| 3781 __ c_d(OLT, f4, f6, 0); |
| 3782 __ c_s(OLT, f14, f16, 2); |
| 3783 __ movt(t2, t1, 0); |
| 3784 __ movt(t3, t1, 2); |
| 3785 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dOlt)) ); |
| 3786 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fOlt)) ); |
| 3787 |
| 3788 __ mov(t2, zero_reg); |
| 3789 __ mov(t3, zero_reg); |
| 3790 __ c_d(ULT, f4, f6, 2); |
| 3791 __ c_s(ULT, f14, f16, 4); |
| 3792 __ movt(t2, t1, 2); |
| 3793 __ movt(t3, t1, 4); |
| 3794 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dUlt)) ); |
| 3795 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fUlt)) ); |
| 3796 |
| 3797 __ mov(t2, zero_reg); |
| 3798 __ mov(t3, zero_reg); |
| 3799 __ c_d(OLE, f4, f6, 4); |
| 3800 __ c_s(OLE, f14, f16, 6); |
| 3801 __ movt(t2, t1, 4); |
| 3802 __ movt(t3, t1, 6); |
| 3803 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dOle)) ); |
| 3804 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fOle)) ); |
| 3805 |
| 3806 __ mov(t2, zero_reg); |
| 3807 __ mov(t3, zero_reg); |
| 3808 __ c_d(ULE, f4, f6, 6); |
| 3809 __ c_s(ULE, f14, f16, 0); |
| 3810 __ movt(t2, t1, 6); |
| 3811 __ movt(t3, t1, 0); |
| 3812 __ sw(t2, MemOperand(a0, OFFSET_OF(TestFloat, dUle)) ); |
| 3813 __ sw(t3, MemOperand(a0, OFFSET_OF(TestFloat, fUle)) ); |
| 3814 |
| 3815 __ jr(ra); |
| 3816 __ nop(); |
| 3817 |
| 3818 CodeDesc desc; |
| 3819 assm.GetCode(&desc); |
| 3820 Handle<Code> code = isolate->factory()->NewCode( |
| 3821 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 3822 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 3823 test.dOp1 = 2.0; |
| 3824 test.dOp2 = 3.0; |
| 3825 test.fOp1 = 2.0; |
| 3826 test.fOp2 = 3.0; |
| 3827 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3828 CHECK_EQ(test.dF, 0); |
| 3829 CHECK_EQ(test.dUn, 0); |
| 3830 CHECK_EQ(test.dEq, 0); |
| 3831 CHECK_EQ(test.dUeq, 0); |
| 3832 CHECK_EQ(test.dOlt, 1); |
| 3833 CHECK_EQ(test.dUlt, 1); |
| 3834 CHECK_EQ(test.dOle, 1); |
| 3835 CHECK_EQ(test.dUle, 1); |
| 3836 CHECK_EQ(test.fF, 0); |
| 3837 CHECK_EQ(test.fUn, 0); |
| 3838 CHECK_EQ(test.fEq, 0); |
| 3839 CHECK_EQ(test.fUeq, 0); |
| 3840 CHECK_EQ(test.fOlt, 1); |
| 3841 CHECK_EQ(test.fUlt, 1); |
| 3842 CHECK_EQ(test.fOle, 1); |
| 3843 CHECK_EQ(test.fUle, 1); |
| 3844 |
| 3845 test.dOp1 = std::numeric_limits<double>::max(); |
| 3846 test.dOp2 = std::numeric_limits<double>::min(); |
| 3847 test.fOp1 = std::numeric_limits<float>::min(); |
| 3848 test.fOp2 = std::numeric_limits<float>::lowest(); |
| 3849 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3850 CHECK_EQ(test.dF, 0); |
| 3851 CHECK_EQ(test.dUn, 0); |
| 3852 CHECK_EQ(test.dEq, 0); |
| 3853 CHECK_EQ(test.dUeq, 0); |
| 3854 CHECK_EQ(test.dOlt, 0); |
| 3855 CHECK_EQ(test.dUlt, 0); |
| 3856 CHECK_EQ(test.dOle, 0); |
| 3857 CHECK_EQ(test.dUle, 0); |
| 3858 CHECK_EQ(test.fF, 0); |
| 3859 CHECK_EQ(test.fUn, 0); |
| 3860 CHECK_EQ(test.fEq, 0); |
| 3861 CHECK_EQ(test.fUeq, 0); |
| 3862 CHECK_EQ(test.fOlt, 0); |
| 3863 CHECK_EQ(test.fUlt, 0); |
| 3864 CHECK_EQ(test.fOle, 0); |
| 3865 CHECK_EQ(test.fUle, 0); |
| 3866 |
| 3867 test.dOp1 = std::numeric_limits<double>::lowest(); |
| 3868 test.dOp2 = std::numeric_limits<double>::lowest(); |
| 3869 test.fOp1 = std::numeric_limits<float>::max(); |
| 3870 test.fOp2 = std::numeric_limits<float>::max(); |
| 3871 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3872 CHECK_EQ(test.dF, 0); |
| 3873 CHECK_EQ(test.dUn, 0); |
| 3874 CHECK_EQ(test.dEq, 1); |
| 3875 CHECK_EQ(test.dUeq, 1); |
| 3876 CHECK_EQ(test.dOlt, 0); |
| 3877 CHECK_EQ(test.dUlt, 0); |
| 3878 CHECK_EQ(test.dOle, 1); |
| 3879 CHECK_EQ(test.dUle, 1); |
| 3880 CHECK_EQ(test.fF, 0); |
| 3881 CHECK_EQ(test.fUn, 0); |
| 3882 CHECK_EQ(test.fEq, 1); |
| 3883 CHECK_EQ(test.fUeq, 1); |
| 3884 CHECK_EQ(test.fOlt, 0); |
| 3885 CHECK_EQ(test.fUlt, 0); |
| 3886 CHECK_EQ(test.fOle, 1); |
| 3887 CHECK_EQ(test.fUle, 1); |
| 3888 |
| 3889 test.dOp1 = std::numeric_limits<double>::quiet_NaN(); |
| 3890 test.dOp2 = 0.0; |
| 3891 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); |
| 3892 test.fOp2 = 0.0; |
| 3893 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 3894 CHECK_EQ(test.dF, 0); |
| 3895 CHECK_EQ(test.dUn, 1); |
| 3896 CHECK_EQ(test.dEq, 0); |
| 3897 CHECK_EQ(test.dUeq, 1); |
| 3898 CHECK_EQ(test.dOlt, 0); |
| 3899 CHECK_EQ(test.dUlt, 1); |
| 3900 CHECK_EQ(test.dOle, 0); |
| 3901 CHECK_EQ(test.dUle, 1); |
| 3902 CHECK_EQ(test.fF, 0); |
| 3903 CHECK_EQ(test.fUn, 1); |
| 3904 CHECK_EQ(test.fEq, 0); |
| 3905 CHECK_EQ(test.fUeq, 1); |
| 3906 CHECK_EQ(test.fOlt, 0); |
| 3907 CHECK_EQ(test.fUlt, 1); |
| 3908 CHECK_EQ(test.fOle, 0); |
| 3909 CHECK_EQ(test.fUle, 1); |
| 3910 } |
| 3911 } |
| 3912 |
| 3913 |
| 3914 TEST(CMP_COND_FMT) { |
| 3915 if (kArchVariant == kMips64r6) { |
| 3916 CcTest::InitializeVM(); |
| 3917 Isolate* isolate = CcTest::i_isolate(); |
| 3918 HandleScope scope(isolate); |
| 3919 MacroAssembler assm(isolate, NULL, 0); |
| 3920 |
| 3921 typedef struct test_float { |
| 3922 double dOp1; |
| 3923 double dOp2; |
| 3924 double dF; |
| 3925 double dUn; |
| 3926 double dEq; |
| 3927 double dUeq; |
| 3928 double dOlt; |
| 3929 double dUlt; |
| 3930 double dOle; |
| 3931 double dUle; |
| 3932 double dOr; |
| 3933 double dUne; |
| 3934 double dNe; |
| 3935 float fOp1; |
| 3936 float fOp2; |
| 3937 float fF; |
| 3938 float fUn; |
| 3939 float fEq; |
| 3940 float fUeq; |
| 3941 float fOlt; |
| 3942 float fUlt; |
| 3943 float fOle; |
| 3944 float fUle; |
| 3945 float fOr; |
| 3946 float fUne; |
| 3947 float fNe; |
| 3948 } TestFloat; |
| 3949 |
| 3950 TestFloat test; |
| 3951 |
| 3952 __ li(t1, 1); |
| 3953 |
| 3954 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, dOp1))); |
| 3955 __ ldc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, dOp2))); |
| 3956 |
| 3957 __ lwc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, fOp1))); |
| 3958 __ lwc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, fOp2))); |
| 3959 |
| 3960 __ cmp_d(F, f2, f4, f6); |
| 3961 __ cmp_s(F, f12, f14, f16); |
| 3962 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dF)) ); |
| 3963 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fF)) ); |
| 3964 |
| 3965 __ cmp_d(UN, f2, f4, f6); |
| 3966 __ cmp_s(UN, f12, f14, f16); |
| 3967 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dUn)) ); |
| 3968 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fUn)) ); |
| 3969 |
| 3970 __ cmp_d(EQ, f2, f4, f6); |
| 3971 __ cmp_s(EQ, f12, f14, f16); |
| 3972 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dEq)) ); |
| 3973 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fEq)) ); |
| 3974 |
| 3975 __ cmp_d(UEQ, f2, f4, f6); |
| 3976 __ cmp_s(UEQ, f12, f14, f16); |
| 3977 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dUeq)) ); |
| 3978 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fUeq)) ); |
| 3979 |
| 3980 __ cmp_d(LT, f2, f4, f6); |
| 3981 __ cmp_s(LT, f12, f14, f16); |
| 3982 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dOlt)) ); |
| 3983 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fOlt)) ); |
| 3984 |
| 3985 __ cmp_d(ULT, f2, f4, f6); |
| 3986 __ cmp_s(ULT, f12, f14, f16); |
| 3987 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dUlt)) ); |
| 3988 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fUlt)) ); |
| 3989 |
| 3990 __ cmp_d(LE, f2, f4, f6); |
| 3991 __ cmp_s(LE, f12, f14, f16); |
| 3992 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dOle)) ); |
| 3993 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fOle)) ); |
| 3994 |
| 3995 __ cmp_d(ULE, f2, f4, f6); |
| 3996 __ cmp_s(ULE, f12, f14, f16); |
| 3997 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dUle)) ); |
| 3998 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fUle)) ); |
| 3999 |
| 4000 __ cmp_d(ORD, f2, f4, f6); |
| 4001 __ cmp_s(ORD, f12, f14, f16); |
| 4002 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dOr)) ); |
| 4003 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fOr)) ); |
| 4004 |
| 4005 __ cmp_d(UNE, f2, f4, f6); |
| 4006 __ cmp_s(UNE, f12, f14, f16); |
| 4007 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dUne)) ); |
| 4008 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fUne)) ); |
| 4009 |
| 4010 __ cmp_d(NE, f2, f4, f6); |
| 4011 __ cmp_s(NE, f12, f14, f16); |
| 4012 __ sdc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, dNe)) ); |
| 4013 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, fNe)) ); |
| 4014 |
| 4015 __ jr(ra); |
| 4016 __ nop(); |
| 4017 |
| 4018 CodeDesc desc; |
| 4019 assm.GetCode(&desc); |
| 4020 Handle<Code> code = isolate->factory()->NewCode( |
| 4021 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4022 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 4023 uint64_t dTrue = 0xFFFFFFFFFFFFFFFF; |
| 4024 uint64_t dFalse = 0x0000000000000000; |
| 4025 uint32_t fTrue = 0xFFFFFFFF; |
| 4026 uint32_t fFalse = 0x00000000; |
| 4027 |
| 4028 test.dOp1 = 2.0; |
| 4029 test.dOp2 = 3.0; |
| 4030 test.fOp1 = 2.0; |
| 4031 test.fOp2 = 3.0; |
| 4032 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4033 CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); |
| 4034 CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); |
| 4035 CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); |
| 4036 CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse); |
| 4037 CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue); |
| 4038 CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue); |
| 4039 CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue); |
| 4040 CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue); |
| 4041 CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue); |
| 4042 CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue); |
| 4043 CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue); |
| 4044 CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse); |
| 4045 CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse); |
| 4046 CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse); |
| 4047 CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse); |
| 4048 CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue); |
| 4049 CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue); |
| 4050 CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue); |
| 4051 CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue); |
| 4052 |
| 4053 test.dOp1 = std::numeric_limits<double>::max(); |
| 4054 test.dOp2 = std::numeric_limits<double>::min(); |
| 4055 test.fOp1 = std::numeric_limits<float>::min(); |
| 4056 test.fOp2 = std::numeric_limits<float>::lowest(); |
| 4057 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4058 CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); |
| 4059 CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); |
| 4060 CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); |
| 4061 CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse); |
| 4062 CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse); |
| 4063 CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse); |
| 4064 CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse); |
| 4065 CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse); |
| 4066 CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue); |
| 4067 CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue); |
| 4068 CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue); |
| 4069 CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse); |
| 4070 CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse); |
| 4071 CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse); |
| 4072 CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse); |
| 4073 CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse); |
| 4074 CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse); |
| 4075 CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse); |
| 4076 CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse); |
| 4077 |
| 4078 test.dOp1 = std::numeric_limits<double>::lowest(); |
| 4079 test.dOp2 = std::numeric_limits<double>::lowest(); |
| 4080 test.fOp1 = std::numeric_limits<float>::max(); |
| 4081 test.fOp2 = std::numeric_limits<float>::max(); |
| 4082 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4083 CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); |
| 4084 CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); |
| 4085 CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue); |
| 4086 CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue); |
| 4087 CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse); |
| 4088 CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse); |
| 4089 CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue); |
| 4090 CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue); |
| 4091 CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue); |
| 4092 CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse); |
| 4093 CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse); |
| 4094 CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse); |
| 4095 CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse); |
| 4096 CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue); |
| 4097 CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue); |
| 4098 CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse); |
| 4099 CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse); |
| 4100 CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue); |
| 4101 CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue); |
| 4102 |
| 4103 test.dOp1 = std::numeric_limits<double>::quiet_NaN(); |
| 4104 test.dOp2 = 0.0; |
| 4105 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); |
| 4106 test.fOp2 = 0.0; |
| 4107 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4108 CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); |
| 4109 CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue); |
| 4110 CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); |
| 4111 CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue); |
| 4112 CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse); |
| 4113 CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue); |
| 4114 CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse); |
| 4115 CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue); |
| 4116 CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse); |
| 4117 CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue); |
| 4118 CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse); |
| 4119 CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse); |
| 4120 CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue); |
| 4121 CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse); |
| 4122 CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue); |
| 4123 CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse); |
| 4124 CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue); |
| 4125 CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse); |
| 4126 CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue); |
| 4127 } |
| 4128 } |
| 4129 |
| 4130 |
| 4131 TEST(CVT) { |
| 4132 CcTest::InitializeVM(); |
| 4133 Isolate* isolate = CcTest::i_isolate(); |
| 4134 HandleScope scope(isolate); |
| 4135 MacroAssembler assm(isolate, NULL, 0); |
| 4136 |
| 4137 typedef struct test_float { |
| 4138 float cvt_d_s_in; |
| 4139 double cvt_d_s_out; |
| 4140 int32_t cvt_d_w_in; |
| 4141 double cvt_d_w_out; |
| 4142 int64_t cvt_d_l_in; |
| 4143 double cvt_d_l_out; |
| 4144 |
| 4145 float cvt_l_s_in; |
| 4146 int64_t cvt_l_s_out; |
| 4147 double cvt_l_d_in; |
| 4148 int64_t cvt_l_d_out; |
| 4149 |
| 4150 double cvt_s_d_in; |
| 4151 float cvt_s_d_out; |
| 4152 int32_t cvt_s_w_in; |
| 4153 float cvt_s_w_out; |
| 4154 int64_t cvt_s_l_in; |
| 4155 float cvt_s_l_out; |
| 4156 |
| 4157 float cvt_w_s_in; |
| 4158 int32_t cvt_w_s_out; |
| 4159 double cvt_w_d_in; |
| 4160 int32_t cvt_w_d_out; |
| 4161 } TestFloat; |
| 4162 |
| 4163 TestFloat test; |
| 4164 |
| 4165 // Save FCSR. |
| 4166 __ cfc1(a1, FCSR); |
| 4167 // Disable FPU exceptions. |
| 4168 __ ctc1(zero_reg, FCSR); |
| 4169 |
| 4170 #define GENERATE_CVT_TEST(x, y, z) \ |
| 4171 __ y##c1(f0, MemOperand(a0, OFFSET_OF(TestFloat, x##_in))); \ |
| 4172 __ x(f0, f0); \ |
| 4173 __ nop(); \ |
| 4174 __ z##c1(f0, MemOperand(a0, OFFSET_OF(TestFloat, x##_out))); |
| 4175 |
| 4176 GENERATE_CVT_TEST(cvt_d_s, lw, sd) |
| 4177 GENERATE_CVT_TEST(cvt_d_w, lw, sd) |
| 4178 GENERATE_CVT_TEST(cvt_d_l, ld, sd) |
| 4179 |
| 4180 GENERATE_CVT_TEST(cvt_l_s, lw, sd) |
| 4181 GENERATE_CVT_TEST(cvt_l_d, ld, sd) |
| 4182 |
| 4183 GENERATE_CVT_TEST(cvt_s_d, ld, sw) |
| 4184 GENERATE_CVT_TEST(cvt_s_w, lw, sw) |
| 4185 GENERATE_CVT_TEST(cvt_s_l, ld, sw) |
| 4186 |
| 4187 GENERATE_CVT_TEST(cvt_w_s, lw, sw) |
| 4188 GENERATE_CVT_TEST(cvt_w_d, ld, sw) |
| 4189 |
| 4190 // Restore FCSR. |
| 4191 __ ctc1(a1, FCSR); |
| 4192 |
| 4193 __ jr(ra); |
| 4194 __ nop(); |
| 4195 |
| 4196 CodeDesc desc; |
| 4197 assm.GetCode(&desc); |
| 4198 Handle<Code> code = isolate->factory()->NewCode( |
| 4199 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4200 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 4201 |
| 4202 test.cvt_d_s_in = -0.51; |
| 4203 test.cvt_d_w_in = -1; |
| 4204 test.cvt_d_l_in = -1; |
| 4205 test.cvt_l_s_in = -0.51; |
| 4206 test.cvt_l_d_in = -0.51; |
| 4207 test.cvt_s_d_in = -0.51; |
| 4208 test.cvt_s_w_in = -1; |
| 4209 test.cvt_s_l_in = -1; |
| 4210 test.cvt_w_s_in = -0.51; |
| 4211 test.cvt_w_d_in = -0.51; |
| 4212 |
| 4213 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4214 CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); |
| 4215 CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); |
| 4216 CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); |
| 4217 CHECK_EQ(test.cvt_l_s_out, -1); |
| 4218 CHECK_EQ(test.cvt_l_d_out, -1); |
| 4219 CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); |
| 4220 CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); |
| 4221 CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); |
| 4222 CHECK_EQ(test.cvt_w_s_out, -1); |
| 4223 CHECK_EQ(test.cvt_w_d_out, -1); |
| 4224 |
| 4225 |
| 4226 test.cvt_d_s_in = 0.49; |
| 4227 test.cvt_d_w_in = 1; |
| 4228 test.cvt_d_l_in = 1; |
| 4229 test.cvt_l_s_in = 0.49; |
| 4230 test.cvt_l_d_in = 0.49; |
| 4231 test.cvt_s_d_in = 0.49; |
| 4232 test.cvt_s_w_in = 1; |
| 4233 test.cvt_s_l_in = 1; |
| 4234 test.cvt_w_s_in = 0.49; |
| 4235 test.cvt_w_d_in = 0.49; |
| 4236 |
| 4237 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4238 CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); |
| 4239 CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); |
| 4240 CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); |
| 4241 CHECK_EQ(test.cvt_l_s_out, 0); |
| 4242 CHECK_EQ(test.cvt_l_d_out, 0); |
| 4243 CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); |
| 4244 CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); |
| 4245 CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); |
| 4246 CHECK_EQ(test.cvt_w_s_out, 0); |
| 4247 CHECK_EQ(test.cvt_w_d_out, 0); |
| 4248 |
| 4249 test.cvt_d_s_in = std::numeric_limits<float>::max(); |
| 4250 test.cvt_d_w_in = std::numeric_limits<int32_t>::max(); |
| 4251 test.cvt_d_l_in = std::numeric_limits<int64_t>::max(); |
| 4252 test.cvt_l_s_in = std::numeric_limits<float>::max(); |
| 4253 test.cvt_l_d_in = std::numeric_limits<double>::max(); |
| 4254 test.cvt_s_d_in = std::numeric_limits<double>::max(); |
| 4255 test.cvt_s_w_in = std::numeric_limits<int32_t>::max(); |
| 4256 test.cvt_s_l_in = std::numeric_limits<int64_t>::max(); |
| 4257 test.cvt_w_s_in = std::numeric_limits<float>::max(); |
| 4258 test.cvt_w_d_in = std::numeric_limits<double>::max(); |
| 4259 |
| 4260 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4261 CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); |
| 4262 CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); |
| 4263 CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); |
| 4264 CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max()); |
| 4265 CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max()); |
| 4266 CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); |
| 4267 CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); |
| 4268 CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); |
| 4269 CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max()); |
| 4270 CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max()); |
| 4271 |
| 4272 |
| 4273 test.cvt_d_s_in = std::numeric_limits<float>::lowest(); |
| 4274 test.cvt_d_w_in = std::numeric_limits<int32_t>::lowest(); |
| 4275 test.cvt_d_l_in = std::numeric_limits<int64_t>::lowest(); |
| 4276 test.cvt_l_s_in = std::numeric_limits<float>::lowest(); |
| 4277 test.cvt_l_d_in = std::numeric_limits<double>::lowest(); |
| 4278 test.cvt_s_d_in = std::numeric_limits<double>::lowest(); |
| 4279 test.cvt_s_w_in = std::numeric_limits<int32_t>::lowest(); |
| 4280 test.cvt_s_l_in = std::numeric_limits<int64_t>::lowest(); |
| 4281 test.cvt_w_s_in = std::numeric_limits<float>::lowest(); |
| 4282 test.cvt_w_d_in = std::numeric_limits<double>::lowest(); |
| 4283 |
| 4284 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4285 CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); |
| 4286 CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); |
| 4287 CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); |
| 4288 // The returned value when converting from fixed-point to float-point |
| 4289 // is not consistent between board, simulator and specification |
| 4290 // in this test case, therefore modifying the test |
| 4291 CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() || |
| 4292 test.cvt_l_s_out == std::numeric_limits<int64_t>::max()); |
| 4293 CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() || |
| 4294 test.cvt_l_d_out == std::numeric_limits<int64_t>::max()); |
| 4295 CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); |
| 4296 CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); |
| 4297 CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); |
| 4298 CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() || |
| 4299 test.cvt_w_s_out == std::numeric_limits<int32_t>::max()); |
| 4300 CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() || |
| 4301 test.cvt_w_d_out == std::numeric_limits<int32_t>::max()); |
| 4302 |
| 4303 |
| 4304 test.cvt_d_s_in = std::numeric_limits<float>::min(); |
| 4305 test.cvt_d_w_in = std::numeric_limits<int32_t>::min(); |
| 4306 test.cvt_d_l_in = std::numeric_limits<int64_t>::min(); |
| 4307 test.cvt_l_s_in = std::numeric_limits<float>::min(); |
| 4308 test.cvt_l_d_in = std::numeric_limits<double>::min(); |
| 4309 test.cvt_s_d_in = std::numeric_limits<double>::min(); |
| 4310 test.cvt_s_w_in = std::numeric_limits<int32_t>::min(); |
| 4311 test.cvt_s_l_in = std::numeric_limits<int64_t>::min(); |
| 4312 test.cvt_w_s_in = std::numeric_limits<float>::min(); |
| 4313 test.cvt_w_d_in = std::numeric_limits<double>::min(); |
| 4314 |
| 4315 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4316 CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); |
| 4317 CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); |
| 4318 CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); |
| 4319 CHECK_EQ(test.cvt_l_s_out, 0); |
| 4320 CHECK_EQ(test.cvt_l_d_out, 0); |
| 4321 CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); |
| 4322 CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); |
| 4323 CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); |
| 4324 CHECK_EQ(test.cvt_w_s_out, 0); |
| 4325 CHECK_EQ(test.cvt_w_d_out, 0); |
| 4326 } |
| 4327 |
| 4328 |
| 4329 TEST(DIV_FMT) { |
| 4330 CcTest::InitializeVM(); |
| 4331 Isolate* isolate = CcTest::i_isolate(); |
| 4332 HandleScope scope(isolate); |
| 4333 MacroAssembler assm(isolate, NULL, 0); |
| 4334 |
| 4335 typedef struct test { |
| 4336 double dOp1; |
| 4337 double dOp2; |
| 4338 double dRes; |
| 4339 float fOp1; |
| 4340 float fOp2; |
| 4341 float fRes; |
| 4342 } Test; |
| 4343 |
| 4344 Test test; |
| 4345 |
| 4346 // Save FCSR. |
| 4347 __ cfc1(a1, FCSR); |
| 4348 // Disable FPU exceptions. |
| 4349 __ ctc1(zero_reg, FCSR); |
| 4350 |
| 4351 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, dOp1)) ); |
| 4352 __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, dOp2)) ); |
| 4353 __ nop(); |
| 4354 __ div_d(f6, f4, f2); |
| 4355 __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, dRes)) ); |
| 4356 |
| 4357 __ lwc1(f4, MemOperand(a0, OFFSET_OF(Test, fOp1)) ); |
| 4358 __ lwc1(f2, MemOperand(a0, OFFSET_OF(Test, fOp2)) ); |
| 4359 __ nop(); |
| 4360 __ div_s(f6, f4, f2); |
| 4361 __ swc1(f6, MemOperand(a0, OFFSET_OF(Test, fRes)) ); |
| 4362 |
| 4363 // Restore FCSR. |
| 4364 __ ctc1(a1, FCSR); |
| 4365 |
| 4366 __ jr(ra); |
| 4367 __ nop(); |
| 4368 CodeDesc desc; |
| 4369 assm.GetCode(&desc); |
| 4370 Handle<Code> code = isolate->factory()->NewCode( |
| 4371 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4372 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 4373 |
| 4374 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4375 |
| 4376 const int test_size = 3; |
| 4377 |
| 4378 double dOp1[test_size] = { |
| 4379 5.0, |
| 4380 DBL_MAX, |
| 4381 DBL_MAX, |
| 4382 }; |
| 4383 double dOp2[test_size] = { |
| 4384 2.0, |
| 4385 2.0, |
| 4386 -DBL_MAX, |
| 4387 }; |
| 4388 double dRes[test_size] = { |
| 4389 2.5, |
| 4390 DBL_MAX / 2.0, |
| 4391 -1.0, |
| 4392 }; |
| 4393 float fOp1[test_size] = { |
| 4394 5.0, |
| 4395 FLT_MAX, |
| 4396 FLT_MAX, |
| 4397 }; |
| 4398 float fOp2[test_size] = { |
| 4399 2.0, |
| 4400 2.0, |
| 4401 -FLT_MAX, |
| 4402 }; |
| 4403 float fRes[test_size] = { |
| 4404 2.5, |
| 4405 FLT_MAX / 2.0, |
| 4406 -1.0, |
| 4407 }; |
| 4408 |
| 4409 for (int i = 0; i < test_size; i++) { |
| 4410 test.dOp1 = dOp1[i]; |
| 4411 test.dOp2 = dOp2[i]; |
| 4412 test.fOp1 = fOp1[i]; |
| 4413 test.fOp2 = fOp2[i]; |
| 4414 |
| 4415 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4416 CHECK_EQ(test.dRes, dRes[i]); |
| 4417 CHECK_EQ(test.fRes, fRes[i]); |
| 4418 } |
| 4419 |
| 4420 test.dOp1 = DBL_MAX; |
| 4421 test.dOp2 = -0.0; |
| 4422 test.fOp1 = FLT_MAX; |
| 4423 test.fOp2 = -0.0; |
| 4424 |
| 4425 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4426 CHECK_EQ(false, std::isfinite(test.dRes)); |
| 4427 CHECK_EQ(false, std::isfinite(test.fRes)); |
| 4428 |
| 4429 test.dOp1 = 0.0; |
| 4430 test.dOp2 = -0.0; |
| 4431 test.fOp1 = 0.0; |
| 4432 test.fOp2 = -0.0; |
| 4433 |
| 4434 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4435 CHECK_EQ(true, std::isnan(test.dRes)); |
| 4436 CHECK_EQ(true, std::isnan(test.fRes)); |
| 4437 |
| 4438 test.dOp1 = std::numeric_limits<double>::quiet_NaN(); |
| 4439 test.dOp2 = -5.0; |
| 4440 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); |
| 4441 test.fOp2 = -5.0; |
| 4442 |
| 4443 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4444 CHECK_EQ(true, std::isnan(test.dRes)); |
| 4445 CHECK_EQ(true, std::isnan(test.fRes)); |
| 4446 } |
| 4447 |
| 4448 |
3287 #undef __ | 4449 #undef __ |
OLD | NEW |