OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); | 515 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); |
516 for (size_t i = 0; i < nr_test_cases; ++i) { | 516 for (size_t i = 0; i < nr_test_cases; ++i) { |
517 uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa); | 517 uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa); |
518 PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64 | 518 PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64 |
519 ", %hhu)\n", | 519 ", %hhu)\n", |
520 tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa); | 520 tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa); |
521 CHECK_EQ(tc[i].expected_res, res); | 521 CHECK_EQ(tc[i].expected_res, res); |
522 } | 522 } |
523 } | 523 } |
524 | 524 |
525 static const std::vector<uint32_t> uint32_test_values() { | 525 static const std::vector<uint32_t> cvt_trunc_uint32_test_values() { |
526 static const uint32_t kValues[] = {0x00000000, 0x00000001, 0x00ffff00, | 526 static const uint32_t kValues[] = {0x00000000, 0x00000001, 0x00ffff00, |
527 0x7fffffff, 0x80000000, 0x80000001, | 527 0x7fffffff, 0x80000000, 0x80000001, |
528 0x80ffff00, 0x8fffffff, 0xffffffff}; | 528 0x80ffff00, 0x8fffffff, 0xffffffff}; |
529 return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]); | 529 return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
530 } | 530 } |
531 | 531 |
532 static const std::vector<int32_t> int32_test_values() { | 532 static const std::vector<int32_t> cvt_trunc_int32_test_values() { |
533 static const int32_t kValues[] = { | 533 static const int32_t kValues[] = { |
534 static_cast<int32_t>(0x00000000), static_cast<int32_t>(0x00000001), | 534 static_cast<int32_t>(0x00000000), static_cast<int32_t>(0x00000001), |
535 static_cast<int32_t>(0x00ffff00), static_cast<int32_t>(0x7fffffff), | 535 static_cast<int32_t>(0x00ffff00), static_cast<int32_t>(0x7fffffff), |
536 static_cast<int32_t>(0x80000000), static_cast<int32_t>(0x80000001), | 536 static_cast<int32_t>(0x80000000), static_cast<int32_t>(0x80000001), |
537 static_cast<int32_t>(0x80ffff00), static_cast<int32_t>(0x8fffffff), | 537 static_cast<int32_t>(0x80ffff00), static_cast<int32_t>(0x8fffffff), |
538 static_cast<int32_t>(0xffffffff)}; | 538 static_cast<int32_t>(0xffffffff)}; |
539 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); | 539 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
540 } | 540 } |
541 | 541 |
542 static const std::vector<uint64_t> uint64_test_values() { | 542 static const std::vector<uint64_t> cvt_trunc_uint64_test_values() { |
543 static const uint64_t kValues[] = { | 543 static const uint64_t kValues[] = { |
544 0x0000000000000000, 0x0000000000000001, 0x0000ffffffff0000, | 544 0x0000000000000000, 0x0000000000000001, 0x0000ffffffff0000, |
545 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000001, | 545 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000001, |
546 0x8000ffffffff0000, 0x8fffffffffffffff, 0xffffffffffffffff}; | 546 0x8000ffffffff0000, 0x8fffffffffffffff, 0xffffffffffffffff}; |
547 return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]); | 547 return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]); |
548 } | 548 } |
549 | 549 |
550 static const std::vector<int64_t> int64_test_values() { | 550 static const std::vector<int64_t> cvt_trunc_int64_test_values() { |
551 static const int64_t kValues[] = {static_cast<int64_t>(0x0000000000000000), | 551 static const int64_t kValues[] = {static_cast<int64_t>(0x0000000000000000), |
552 static_cast<int64_t>(0x0000000000000001), | 552 static_cast<int64_t>(0x0000000000000001), |
553 static_cast<int64_t>(0x0000ffffffff0000), | 553 static_cast<int64_t>(0x0000ffffffff0000), |
554 static_cast<int64_t>(0x7fffffffffffffff), | 554 static_cast<int64_t>(0x7fffffffffffffff), |
555 static_cast<int64_t>(0x8000000000000000), | 555 static_cast<int64_t>(0x8000000000000000), |
556 static_cast<int64_t>(0x8000000000000001), | 556 static_cast<int64_t>(0x8000000000000001), |
557 static_cast<int64_t>(0x8000ffffffff0000), | 557 static_cast<int64_t>(0x8000ffffffff0000), |
558 static_cast<int64_t>(0x8fffffffffffffff), | 558 static_cast<int64_t>(0x8fffffffffffffff), |
559 static_cast<int64_t>(0xffffffffffffffff)}; | 559 static_cast<int64_t>(0xffffffffffffffff)}; |
560 return std::vector<int64_t>(&kValues[0], &kValues[arraysize(kValues)]); | 560 return std::vector<int64_t>(&kValues[0], &kValues[arraysize(kValues)]); |
561 } | 561 } |
562 | 562 |
563 // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... } | 563 // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... } |
564 #define FOR_INPUTS(ctype, itype, var) \ | 564 #define FOR_INPUTS(ctype, itype, var, test_vector) \ |
565 std::vector<ctype> var##_vec = itype##_test_values(); \ | 565 std::vector<ctype> var##_vec = test_vector(); \ |
566 for (std::vector<ctype>::iterator var = var##_vec.begin(); \ | 566 for (std::vector<ctype>::iterator var = var##_vec.begin(); \ |
567 var != var##_vec.end(); ++var) | 567 var != var##_vec.end(); ++var) |
568 | 568 |
569 #define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var) | 569 #define FOR_INPUTS2(ctype, itype, var, var2, test_vector) \ |
570 #define FOR_INT64_INPUTS(var) FOR_INPUTS(int64_t, int64, var) | 570 std::vector<ctype> var##_vec = test_vector(); \ |
571 #define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var) | 571 std::vector<ctype>::iterator var; \ |
572 #define FOR_UINT64_INPUTS(var) FOR_INPUTS(uint64_t, uint64, var) | 572 std::vector<ctype>::reverse_iterator var2; \ |
| 573 for (var = var##_vec.begin(), var2 = var##_vec.rbegin(); \ |
| 574 var != var##_vec.end(); ++var, ++var2) |
| 575 |
| 576 #define FOR_INT32_INPUTS(var, test_vector) \ |
| 577 FOR_INPUTS(int32_t, int32, var, test_vector) |
| 578 #define FOR_INT32_INPUTS2(var, var2, test_vector) \ |
| 579 FOR_INPUTS2(int32_t, int32, var, var2, test_vector) |
| 580 #define FOR_INT64_INPUTS(var, test_vector) \ |
| 581 FOR_INPUTS(int64_t, int64, var, test_vector) |
| 582 #define FOR_UINT32_INPUTS(var, test_vector) \ |
| 583 FOR_INPUTS(uint32_t, uint32, var, test_vector) |
| 584 #define FOR_UINT64_INPUTS(var, test_vector) \ |
| 585 FOR_INPUTS(uint64_t, uint64, var, test_vector) |
573 | 586 |
574 template <typename RET_TYPE, typename IN_TYPE, typename Func> | 587 template <typename RET_TYPE, typename IN_TYPE, typename Func> |
575 RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) { | 588 RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) { |
576 typedef RET_TYPE (*F_CVT)(IN_TYPE x0, int x1, int x2, int x3, int x4); | 589 typedef RET_TYPE (*F_CVT)(IN_TYPE x0, int x1, int x2, int x3, int x4); |
577 | 590 |
578 Isolate* isolate = CcTest::i_isolate(); | 591 Isolate* isolate = CcTest::i_isolate(); |
579 HandleScope scope(isolate); | 592 HandleScope scope(isolate); |
580 MacroAssembler assm(isolate, nullptr, 0, | 593 MacroAssembler assm(isolate, nullptr, 0, |
581 v8::internal::CodeObjectRequired::kYes); | 594 v8::internal::CodeObjectRequired::kYes); |
582 MacroAssembler* masm = &assm; | 595 MacroAssembler* masm = &assm; |
583 | 596 |
584 GenerateConvertInstructionFunc(masm); | 597 GenerateConvertInstructionFunc(masm); |
585 __ dmfc1(v0, f2); | 598 __ dmfc1(v0, f2); |
586 __ jr(ra); | 599 __ jr(ra); |
587 __ nop(); | 600 __ nop(); |
588 | 601 |
589 CodeDesc desc; | 602 CodeDesc desc; |
590 assm.GetCode(&desc); | 603 assm.GetCode(&desc); |
591 Handle<Code> code = isolate->factory()->NewCode( | 604 Handle<Code> code = isolate->factory()->NewCode( |
592 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 605 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
593 | 606 |
594 F_CVT f = FUNCTION_CAST<F_CVT>(code->entry()); | 607 F_CVT f = FUNCTION_CAST<F_CVT>(code->entry()); |
595 | 608 |
596 return reinterpret_cast<RET_TYPE>( | 609 return reinterpret_cast<RET_TYPE>( |
597 CALL_GENERATED_CODE(isolate, f, x, 0, 0, 0, 0)); | 610 CALL_GENERATED_CODE(isolate, f, x, 0, 0, 0, 0)); |
598 } | 611 } |
599 | 612 |
600 TEST(Cvt_s_uw_Trunc_uw_s) { | 613 TEST(Cvt_s_uw_Trunc_uw_s) { |
601 CcTest::InitializeVM(); | 614 CcTest::InitializeVM(); |
602 FOR_UINT32_INPUTS(i) { | 615 FOR_UINT32_INPUTS(i, cvt_trunc_uint32_test_values) { |
603 uint32_t input = *i; | 616 uint32_t input = *i; |
604 CHECK_EQ(static_cast<float>(input), | 617 CHECK_EQ(static_cast<float>(input), |
605 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { | 618 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { |
606 __ Cvt_s_uw(f0, a0); | 619 __ Cvt_s_uw(f0, a0); |
607 __ Trunc_uw_s(f2, f0, f1); | 620 __ Trunc_uw_s(f2, f0, f1); |
608 })); | 621 })); |
609 } | 622 } |
610 } | 623 } |
611 | 624 |
612 TEST(Cvt_s_ul_Trunc_ul_s) { | 625 TEST(Cvt_s_ul_Trunc_ul_s) { |
613 CcTest::InitializeVM(); | 626 CcTest::InitializeVM(); |
614 FOR_UINT64_INPUTS(i) { | 627 FOR_UINT64_INPUTS(i, cvt_trunc_uint64_test_values) { |
615 uint64_t input = *i; | 628 uint64_t input = *i; |
616 CHECK_EQ(static_cast<float>(input), | 629 CHECK_EQ(static_cast<float>(input), |
617 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { | 630 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { |
618 __ Cvt_s_ul(f0, a0); | 631 __ Cvt_s_ul(f0, a0); |
619 __ Trunc_ul_s(f2, f0, f1, v0); | 632 __ Trunc_ul_s(f2, f0, f1, v0); |
620 })); | 633 })); |
621 } | 634 } |
622 } | 635 } |
623 | 636 |
624 TEST(Cvt_d_ul_Trunc_ul_d) { | 637 TEST(Cvt_d_ul_Trunc_ul_d) { |
625 CcTest::InitializeVM(); | 638 CcTest::InitializeVM(); |
626 FOR_UINT64_INPUTS(i) { | 639 FOR_UINT64_INPUTS(i, cvt_trunc_uint64_test_values) { |
627 uint64_t input = *i; | 640 uint64_t input = *i; |
628 CHECK_EQ(static_cast<double>(input), | 641 CHECK_EQ(static_cast<double>(input), |
629 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { | 642 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { |
630 __ Cvt_d_ul(f0, a0); | 643 __ Cvt_d_ul(f0, a0); |
631 __ Trunc_ul_d(f2, f0, f1, v0); | 644 __ Trunc_ul_d(f2, f0, f1, v0); |
632 })); | 645 })); |
633 } | 646 } |
634 } | 647 } |
635 | 648 |
636 TEST(cvt_d_l_Trunc_l_d) { | 649 TEST(cvt_d_l_Trunc_l_d) { |
637 CcTest::InitializeVM(); | 650 CcTest::InitializeVM(); |
638 FOR_INT64_INPUTS(i) { | 651 FOR_INT64_INPUTS(i, cvt_trunc_int64_test_values) { |
639 int64_t input = *i; | 652 int64_t input = *i; |
640 CHECK_EQ(static_cast<double>(input), | 653 CHECK_EQ(static_cast<double>(input), |
641 run_Cvt<int64_t>(input, [](MacroAssembler* masm) { | 654 run_Cvt<int64_t>(input, [](MacroAssembler* masm) { |
642 __ dmtc1(a0, f4); | 655 __ dmtc1(a0, f4); |
643 __ cvt_d_l(f0, f4); | 656 __ cvt_d_l(f0, f4); |
644 __ Trunc_l_d(f2, f0); | 657 __ Trunc_l_d(f2, f0); |
645 })); | 658 })); |
646 } | 659 } |
647 } | 660 } |
648 | 661 |
649 TEST(cvt_d_l_Trunc_l_ud) { | 662 TEST(cvt_d_l_Trunc_l_ud) { |
650 CcTest::InitializeVM(); | 663 CcTest::InitializeVM(); |
651 FOR_INT64_INPUTS(i) { | 664 FOR_INT64_INPUTS(i, cvt_trunc_int64_test_values) { |
652 int64_t input = *i; | 665 int64_t input = *i; |
653 uint64_t abs_input = (input < 0) ? -input : input; | 666 uint64_t abs_input = (input < 0) ? -input : input; |
654 CHECK_EQ(static_cast<double>(abs_input), | 667 CHECK_EQ(static_cast<double>(abs_input), |
655 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { | 668 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { |
656 __ dmtc1(a0, f4); | 669 __ dmtc1(a0, f4); |
657 __ cvt_d_l(f0, f4); | 670 __ cvt_d_l(f0, f4); |
658 __ Trunc_l_ud(f2, f0, f6); | 671 __ Trunc_l_ud(f2, f0, f6); |
659 })); | 672 })); |
660 } | 673 } |
661 } | 674 } |
662 | 675 |
663 TEST(cvt_d_w_Trunc_w_d) { | 676 TEST(cvt_d_w_Trunc_w_d) { |
664 CcTest::InitializeVM(); | 677 CcTest::InitializeVM(); |
665 FOR_INT32_INPUTS(i) { | 678 FOR_INT32_INPUTS(i, cvt_trunc_int32_test_values) { |
666 int32_t input = *i; | 679 int32_t input = *i; |
667 CHECK_EQ(static_cast<double>(input), | 680 CHECK_EQ(static_cast<double>(input), |
668 run_Cvt<int64_t>(input, [](MacroAssembler* masm) { | 681 run_Cvt<int64_t>(input, [](MacroAssembler* masm) { |
669 __ mtc1(a0, f4); | 682 __ mtc1(a0, f4); |
670 __ cvt_d_w(f0, f4); | 683 __ cvt_d_w(f0, f4); |
671 __ Trunc_w_d(f2, f0); | 684 __ Trunc_w_d(f2, f0); |
672 __ mfc1(v1, f2); | 685 __ mfc1(v1, f2); |
673 __ dmtc1(v1, f2); | 686 __ dmtc1(v1, f2); |
674 })); | 687 })); |
675 } | 688 } |
676 } | 689 } |
677 | 690 |
| 691 template <typename IN_TYPE, typename Func> |
| 692 bool run_Unaligned(char* memory_buffer, int32_t in_offset, int32_t out_offset, |
| 693 IN_TYPE value, Func GenerateUnalignedInstructionFunc) { |
| 694 typedef int32_t (*F_CVT)(char* x0, int x1, int x2, int x3, int x4); |
| 695 |
| 696 Isolate* isolate = CcTest::i_isolate(); |
| 697 HandleScope scope(isolate); |
| 698 MacroAssembler assm(isolate, nullptr, 0, |
| 699 v8::internal::CodeObjectRequired::kYes); |
| 700 MacroAssembler* masm = &assm; |
| 701 IN_TYPE res; |
| 702 |
| 703 GenerateUnalignedInstructionFunc(masm, in_offset, out_offset); |
| 704 __ jr(ra); |
| 705 __ nop(); |
| 706 |
| 707 CodeDesc desc; |
| 708 assm.GetCode(&desc); |
| 709 Handle<Code> code = isolate->factory()->NewCode( |
| 710 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 711 |
| 712 F_CVT f = FUNCTION_CAST<F_CVT>(code->entry()); |
| 713 |
| 714 MemCopy(memory_buffer + in_offset, &value, sizeof(IN_TYPE)); |
| 715 CALL_GENERATED_CODE(isolate, f, memory_buffer, 0, 0, 0, 0); |
| 716 MemCopy(&res, memory_buffer + out_offset, sizeof(IN_TYPE)); |
| 717 |
| 718 return res == value; |
| 719 } |
| 720 |
| 721 static const std::vector<uint64_t> unsigned_test_values() { |
| 722 static const uint64_t kValues[] = { |
| 723 0x2180f18a06384414, 0x000a714532102277, 0xbc1acccf180649f0, |
| 724 0x8000000080008000, 0x0000000000000001, 0xffffffffffffffff, |
| 725 }; |
| 726 return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]); |
| 727 } |
| 728 |
| 729 static const std::vector<int32_t> unsigned_test_offset() { |
| 730 static const int32_t kValues[] = {// value, offset |
| 731 -132 * KB, -21 * KB, 0, 19 * KB, 135 * KB}; |
| 732 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
| 733 } |
| 734 |
| 735 static const std::vector<int32_t> unsigned_test_offset_increment() { |
| 736 static const int32_t kValues[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}; |
| 737 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
| 738 } |
| 739 |
| 740 TEST(Ulh) { |
| 741 CcTest::InitializeVM(); |
| 742 |
| 743 static const int kBufferSize = 300 * KB; |
| 744 char memory_buffer[kBufferSize]; |
| 745 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 746 |
| 747 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 748 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 749 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 750 uint16_t value = static_cast<uint64_t>(*i & 0xFFFF); |
| 751 int32_t in_offset = *j1 + *k1; |
| 752 int32_t out_offset = *j2 + *k2; |
| 753 |
| 754 CHECK_EQ(true, run_Unaligned<uint16_t>( |
| 755 buffer_middle, in_offset, out_offset, value, |
| 756 [](MacroAssembler* masm, int32_t in_offset, |
| 757 int32_t out_offset) { |
| 758 __ Ulh(v0, MemOperand(a0, in_offset)); |
| 759 __ Ush(v0, MemOperand(a0, out_offset), v0); |
| 760 })); |
| 761 CHECK_EQ(true, run_Unaligned<uint16_t>( |
| 762 buffer_middle, in_offset, out_offset, value, |
| 763 [](MacroAssembler* masm, int32_t in_offset, |
| 764 int32_t out_offset) { |
| 765 __ mov(t0, a0); |
| 766 __ Ulh(a0, MemOperand(a0, in_offset)); |
| 767 __ Ush(a0, MemOperand(t0, out_offset), v0); |
| 768 })); |
| 769 CHECK_EQ(true, run_Unaligned<uint16_t>( |
| 770 buffer_middle, in_offset, out_offset, value, |
| 771 [](MacroAssembler* masm, int32_t in_offset, |
| 772 int32_t out_offset) { |
| 773 __ mov(t0, a0); |
| 774 __ Ulhu(a0, MemOperand(a0, in_offset)); |
| 775 __ Ush(a0, MemOperand(t0, out_offset), t1); |
| 776 })); |
| 777 CHECK_EQ(true, run_Unaligned<uint16_t>( |
| 778 buffer_middle, in_offset, out_offset, value, |
| 779 [](MacroAssembler* masm, int32_t in_offset, |
| 780 int32_t out_offset) { |
| 781 __ Ulhu(v0, MemOperand(a0, in_offset)); |
| 782 __ Ush(v0, MemOperand(a0, out_offset), t1); |
| 783 })); |
| 784 } |
| 785 } |
| 786 } |
| 787 } |
| 788 |
| 789 TEST(Ulh_bitextension) { |
| 790 CcTest::InitializeVM(); |
| 791 |
| 792 static const int kBufferSize = 300 * KB; |
| 793 char memory_buffer[kBufferSize]; |
| 794 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 795 |
| 796 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 797 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 798 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 799 uint16_t value = static_cast<uint64_t>(*i & 0xFFFF); |
| 800 int32_t in_offset = *j1 + *k1; |
| 801 int32_t out_offset = *j2 + *k2; |
| 802 |
| 803 CHECK_EQ(true, run_Unaligned<uint16_t>( |
| 804 buffer_middle, in_offset, out_offset, value, |
| 805 [](MacroAssembler* masm, int32_t in_offset, |
| 806 int32_t out_offset) { |
| 807 Label success, fail, end, different; |
| 808 __ Ulh(t0, MemOperand(a0, in_offset)); |
| 809 __ Ulhu(t1, MemOperand(a0, in_offset)); |
| 810 __ Branch(&different, ne, t0, Operand(t1)); |
| 811 |
| 812 // If signed and unsigned values are same, check |
| 813 // the upper bits to see if they are zero |
| 814 __ sra(t0, t0, 15); |
| 815 __ Branch(&success, eq, t0, Operand(zero_reg)); |
| 816 __ Branch(&fail); |
| 817 |
| 818 // If signed and unsigned values are different, |
| 819 // check that the upper bits are complementary |
| 820 __ bind(&different); |
| 821 __ sra(t1, t1, 15); |
| 822 __ Branch(&fail, ne, t1, Operand(1)); |
| 823 __ sra(t0, t0, 15); |
| 824 __ addiu(t0, t0, 1); |
| 825 __ Branch(&fail, ne, t0, Operand(zero_reg)); |
| 826 // Fall through to success |
| 827 |
| 828 __ bind(&success); |
| 829 __ Ulh(t0, MemOperand(a0, in_offset)); |
| 830 __ Ush(t0, MemOperand(a0, out_offset), v0); |
| 831 __ Branch(&end); |
| 832 __ bind(&fail); |
| 833 __ Ush(zero_reg, MemOperand(a0, out_offset), v0); |
| 834 __ bind(&end); |
| 835 })); |
| 836 } |
| 837 } |
| 838 } |
| 839 } |
| 840 |
| 841 TEST(Ulw) { |
| 842 CcTest::InitializeVM(); |
| 843 |
| 844 static const int kBufferSize = 300 * KB; |
| 845 char memory_buffer[kBufferSize]; |
| 846 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 847 |
| 848 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 849 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 850 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 851 uint32_t value = static_cast<uint32_t>(*i & 0xFFFFFFFF); |
| 852 int32_t in_offset = *j1 + *k1; |
| 853 int32_t out_offset = *j2 + *k2; |
| 854 |
| 855 CHECK_EQ(true, run_Unaligned<uint32_t>( |
| 856 buffer_middle, in_offset, out_offset, value, |
| 857 [](MacroAssembler* masm, int32_t in_offset, |
| 858 int32_t out_offset) { |
| 859 __ Ulw(v0, MemOperand(a0, in_offset)); |
| 860 __ Usw(v0, MemOperand(a0, out_offset)); |
| 861 })); |
| 862 CHECK_EQ(true, |
| 863 run_Unaligned<uint32_t>( |
| 864 buffer_middle, in_offset, out_offset, (uint32_t)value, |
| 865 [](MacroAssembler* masm, int32_t in_offset, |
| 866 int32_t out_offset) { |
| 867 __ mov(t0, a0); |
| 868 __ Ulw(a0, MemOperand(a0, in_offset)); |
| 869 __ Usw(a0, MemOperand(t0, out_offset)); |
| 870 })); |
| 871 CHECK_EQ(true, run_Unaligned<uint32_t>( |
| 872 buffer_middle, in_offset, out_offset, value, |
| 873 [](MacroAssembler* masm, int32_t in_offset, |
| 874 int32_t out_offset) { |
| 875 __ Ulwu(v0, MemOperand(a0, in_offset)); |
| 876 __ Usw(v0, MemOperand(a0, out_offset)); |
| 877 })); |
| 878 CHECK_EQ(true, |
| 879 run_Unaligned<uint32_t>( |
| 880 buffer_middle, in_offset, out_offset, (uint32_t)value, |
| 881 [](MacroAssembler* masm, int32_t in_offset, |
| 882 int32_t out_offset) { |
| 883 __ mov(t0, a0); |
| 884 __ Ulwu(a0, MemOperand(a0, in_offset)); |
| 885 __ Usw(a0, MemOperand(t0, out_offset)); |
| 886 })); |
| 887 } |
| 888 } |
| 889 } |
| 890 } |
| 891 |
| 892 TEST(Ulw_extension) { |
| 893 CcTest::InitializeVM(); |
| 894 |
| 895 static const int kBufferSize = 300 * KB; |
| 896 char memory_buffer[kBufferSize]; |
| 897 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 898 |
| 899 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 900 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 901 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 902 uint32_t value = static_cast<uint32_t>(*i & 0xFFFFFFFF); |
| 903 int32_t in_offset = *j1 + *k1; |
| 904 int32_t out_offset = *j2 + *k2; |
| 905 |
| 906 CHECK_EQ(true, run_Unaligned<uint32_t>( |
| 907 buffer_middle, in_offset, out_offset, value, |
| 908 [](MacroAssembler* masm, int32_t in_offset, |
| 909 int32_t out_offset) { |
| 910 Label success, fail, end, different; |
| 911 __ Ulw(t0, MemOperand(a0, in_offset)); |
| 912 __ Ulwu(t1, MemOperand(a0, in_offset)); |
| 913 __ Branch(&different, ne, t0, Operand(t1)); |
| 914 |
| 915 // If signed and unsigned values are same, check |
| 916 // the upper bits to see if they are zero |
| 917 __ dsra(t0, t0, 31); |
| 918 __ Branch(&success, eq, t0, Operand(zero_reg)); |
| 919 __ Branch(&fail); |
| 920 |
| 921 // If signed and unsigned values are different, |
| 922 // check that the upper bits are complementary |
| 923 __ bind(&different); |
| 924 __ dsra(t1, t1, 31); |
| 925 __ Branch(&fail, ne, t1, Operand(1)); |
| 926 __ dsra(t0, t0, 31); |
| 927 __ daddiu(t0, t0, 1); |
| 928 __ Branch(&fail, ne, t0, Operand(zero_reg)); |
| 929 // Fall through to success |
| 930 |
| 931 __ bind(&success); |
| 932 __ Ulw(t0, MemOperand(a0, in_offset)); |
| 933 __ Usw(t0, MemOperand(a0, out_offset)); |
| 934 __ Branch(&end); |
| 935 __ bind(&fail); |
| 936 __ Usw(zero_reg, MemOperand(a0, out_offset)); |
| 937 __ bind(&end); |
| 938 })); |
| 939 } |
| 940 } |
| 941 } |
| 942 } |
| 943 |
| 944 TEST(Uld) { |
| 945 CcTest::InitializeVM(); |
| 946 |
| 947 static const int kBufferSize = 300 * KB; |
| 948 char memory_buffer[kBufferSize]; |
| 949 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 950 |
| 951 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 952 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 953 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 954 uint64_t value = *i; |
| 955 int32_t in_offset = *j1 + *k1; |
| 956 int32_t out_offset = *j2 + *k2; |
| 957 |
| 958 CHECK_EQ(true, run_Unaligned<uint64_t>( |
| 959 buffer_middle, in_offset, out_offset, value, |
| 960 [](MacroAssembler* masm, int32_t in_offset, |
| 961 int32_t out_offset) { |
| 962 __ Uld(v0, MemOperand(a0, in_offset)); |
| 963 __ Usd(v0, MemOperand(a0, out_offset)); |
| 964 })); |
| 965 CHECK_EQ(true, |
| 966 run_Unaligned<uint64_t>( |
| 967 buffer_middle, in_offset, out_offset, (uint32_t)value, |
| 968 [](MacroAssembler* masm, int32_t in_offset, |
| 969 int32_t out_offset) { |
| 970 __ mov(t0, a0); |
| 971 __ Uld(a0, MemOperand(a0, in_offset)); |
| 972 __ Usd(a0, MemOperand(t0, out_offset)); |
| 973 })); |
| 974 } |
| 975 } |
| 976 } |
| 977 } |
| 978 |
| 979 TEST(Ulwc1) { |
| 980 CcTest::InitializeVM(); |
| 981 |
| 982 static const int kBufferSize = 300 * KB; |
| 983 char memory_buffer[kBufferSize]; |
| 984 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 985 |
| 986 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 987 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 988 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 989 float value = static_cast<float>(*i & 0xFFFFFFFF); |
| 990 int32_t in_offset = *j1 + *k1; |
| 991 int32_t out_offset = *j2 + *k2; |
| 992 |
| 993 CHECK_EQ(true, run_Unaligned<float>( |
| 994 buffer_middle, in_offset, out_offset, value, |
| 995 [](MacroAssembler* masm, int32_t in_offset, |
| 996 int32_t out_offset) { |
| 997 __ Ulwc1(f0, MemOperand(a0, in_offset), t0); |
| 998 __ Uswc1(f0, MemOperand(a0, out_offset), t0); |
| 999 })); |
| 1000 } |
| 1001 } |
| 1002 } |
| 1003 } |
| 1004 |
| 1005 TEST(Uldc1) { |
| 1006 CcTest::InitializeVM(); |
| 1007 |
| 1008 static const int kBufferSize = 300 * KB; |
| 1009 char memory_buffer[kBufferSize]; |
| 1010 char* buffer_middle = memory_buffer + (kBufferSize / 2); |
| 1011 |
| 1012 FOR_UINT64_INPUTS(i, unsigned_test_values) { |
| 1013 FOR_INT32_INPUTS2(j1, j2, unsigned_test_offset) { |
| 1014 FOR_INT32_INPUTS2(k1, k2, unsigned_test_offset_increment) { |
| 1015 double value = static_cast<double>(*i); |
| 1016 int32_t in_offset = *j1 + *k1; |
| 1017 int32_t out_offset = *j2 + *k2; |
| 1018 |
| 1019 CHECK_EQ(true, run_Unaligned<double>( |
| 1020 buffer_middle, in_offset, out_offset, value, |
| 1021 [](MacroAssembler* masm, int32_t in_offset, |
| 1022 int32_t out_offset) { |
| 1023 __ Uldc1(f0, MemOperand(a0, in_offset), t0); |
| 1024 __ Usdc1(f0, MemOperand(a0, out_offset), t0); |
| 1025 })); |
| 1026 } |
| 1027 } |
| 1028 } |
| 1029 } |
| 1030 |
678 #undef __ | 1031 #undef __ |
OLD | NEW |