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

Side by Side Diff: test/cctest/test-macro-assembler-mips64.cc

Issue 1857193002: MIPS: Add tests for AddBranchOvf and SubBranchOvf macro instructions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address code review remarks Created 4 years, 8 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 | « test/cctest/test-macro-assembler-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); 516 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
517 for (size_t i = 0; i < nr_test_cases; ++i) { 517 for (size_t i = 0; i < nr_test_cases; ++i) {
518 uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa); 518 uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa);
519 PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64 519 PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64
520 ", %hhu)\n", 520 ", %hhu)\n",
521 tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa); 521 tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa);
522 CHECK_EQ(tc[i].expected_res, res); 522 CHECK_EQ(tc[i].expected_res, res);
523 } 523 }
524 } 524 }
525 525
526 static const std::vector<uint32_t> uint32_test_values() { 526 static const std::vector<uint32_t> cvt_trunc_uint32_test_values() {
527 static const uint32_t kValues[] = {0x00000000, 0x00000001, 0x00ffff00, 527 static const uint32_t kValues[] = {0x00000000, 0x00000001, 0x00ffff00,
528 0x7fffffff, 0x80000000, 0x80000001, 528 0x7fffffff, 0x80000000, 0x80000001,
529 0x80ffff00, 0x8fffffff, 0xffffffff}; 529 0x80ffff00, 0x8fffffff, 0xffffffff};
530 return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]); 530 return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]);
531 } 531 }
532 532
533 static const std::vector<int32_t> int32_test_values() { 533 static const std::vector<int32_t> cvt_trunc_int32_test_values() {
534 static const int32_t kValues[] = { 534 static const int32_t kValues[] = {
535 static_cast<int32_t>(0x00000000), static_cast<int32_t>(0x00000001), 535 static_cast<int32_t>(0x00000000), static_cast<int32_t>(0x00000001),
536 static_cast<int32_t>(0x00ffff00), static_cast<int32_t>(0x7fffffff), 536 static_cast<int32_t>(0x00ffff00), static_cast<int32_t>(0x7fffffff),
537 static_cast<int32_t>(0x80000000), static_cast<int32_t>(0x80000001), 537 static_cast<int32_t>(0x80000000), static_cast<int32_t>(0x80000001),
538 static_cast<int32_t>(0x80ffff00), static_cast<int32_t>(0x8fffffff), 538 static_cast<int32_t>(0x80ffff00), static_cast<int32_t>(0x8fffffff),
539 static_cast<int32_t>(0xffffffff)}; 539 static_cast<int32_t>(0xffffffff)};
540 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); 540 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]);
541 } 541 }
542 542
543 static const std::vector<uint64_t> uint64_test_values() { 543 static const std::vector<uint64_t> cvt_trunc_uint64_test_values() {
544 static const uint64_t kValues[] = { 544 static const uint64_t kValues[] = {
545 0x0000000000000000, 0x0000000000000001, 0x0000ffffffff0000, 545 0x0000000000000000, 0x0000000000000001, 0x0000ffffffff0000,
546 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000001, 546 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000001,
547 0x8000ffffffff0000, 0x8fffffffffffffff, 0xffffffffffffffff}; 547 0x8000ffffffff0000, 0x8fffffffffffffff, 0xffffffffffffffff};
548 return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]); 548 return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]);
549 } 549 }
550 550
551 static const std::vector<int64_t> int64_test_values() { 551 static const std::vector<int64_t> cvt_trunc_int64_test_values() {
552 static const int64_t kValues[] = {static_cast<int64_t>(0x0000000000000000), 552 static const int64_t kValues[] = {static_cast<int64_t>(0x0000000000000000),
553 static_cast<int64_t>(0x0000000000000001), 553 static_cast<int64_t>(0x0000000000000001),
554 static_cast<int64_t>(0x0000ffffffff0000), 554 static_cast<int64_t>(0x0000ffffffff0000),
555 static_cast<int64_t>(0x7fffffffffffffff), 555 static_cast<int64_t>(0x7fffffffffffffff),
556 static_cast<int64_t>(0x8000000000000000), 556 static_cast<int64_t>(0x8000000000000000),
557 static_cast<int64_t>(0x8000000000000001), 557 static_cast<int64_t>(0x8000000000000001),
558 static_cast<int64_t>(0x8000ffffffff0000), 558 static_cast<int64_t>(0x8000ffffffff0000),
559 static_cast<int64_t>(0x8fffffffffffffff), 559 static_cast<int64_t>(0x8fffffffffffffff),
560 static_cast<int64_t>(0xffffffffffffffff)}; 560 static_cast<int64_t>(0xffffffffffffffff)};
561 return std::vector<int64_t>(&kValues[0], &kValues[arraysize(kValues)]); 561 return std::vector<int64_t>(&kValues[0], &kValues[arraysize(kValues)]);
562 } 562 }
563 563
564 // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... } 564 // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... }
565 #define FOR_INPUTS(ctype, itype, var) \ 565 #define FOR_INPUTS(ctype, itype, var, test_vector) \
566 std::vector<ctype> var##_vec = itype##_test_values(); \ 566 std::vector<ctype> var##_vec = test_vector(); \
567 for (std::vector<ctype>::iterator var = var##_vec.begin(); \ 567 for (std::vector<ctype>::iterator var = var##_vec.begin(); \
568 var != var##_vec.end(); ++var) 568 var != var##_vec.end(); ++var)
569 569
570 #define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var) 570 #define FOR_ENUM_INPUTS(var, type, test_vector) \
571 #define FOR_INT64_INPUTS(var) FOR_INPUTS(int64_t, int64, var) 571 FOR_INPUTS(enum type, type, var, test_vector)
572 #define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var) 572 #define FOR_STRUCT_INPUTS(var, type, test_vector) \
573 #define FOR_UINT64_INPUTS(var) FOR_INPUTS(uint64_t, uint64, var) 573 FOR_INPUTS(struct type, type, var, test_vector)
574 #define FOR_INT32_INPUTS(var, test_vector) \
575 FOR_INPUTS(int32_t, int32, var, test_vector)
576 #define FOR_INT64_INPUTS(var, test_vector) \
577 FOR_INPUTS(int64_t, int64, var, test_vector)
578 #define FOR_UINT32_INPUTS(var, test_vector) \
579 FOR_INPUTS(uint32_t, uint32, var, test_vector)
580 #define FOR_UINT64_INPUTS(var, test_vector) \
581 FOR_INPUTS(uint64_t, uint64, var, test_vector)
574 582
575 template <typename RET_TYPE, typename IN_TYPE, typename Func> 583 template <typename RET_TYPE, typename IN_TYPE, typename Func>
576 RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) { 584 RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) {
577 typedef RET_TYPE (*F_CVT)(IN_TYPE x0, int x1, int x2, int x3, int x4); 585 typedef RET_TYPE (*F_CVT)(IN_TYPE x0, int x1, int x2, int x3, int x4);
578 586
579 Isolate* isolate = CcTest::i_isolate(); 587 Isolate* isolate = CcTest::i_isolate();
580 HandleScope scope(isolate); 588 HandleScope scope(isolate);
581 MacroAssembler assm(isolate, nullptr, 0, 589 MacroAssembler assm(isolate, nullptr, 0,
582 v8::internal::CodeObjectRequired::kYes); 590 v8::internal::CodeObjectRequired::kYes);
583 MacroAssembler* masm = &assm; 591 MacroAssembler* masm = &assm;
584 592
585 GenerateConvertInstructionFunc(masm); 593 GenerateConvertInstructionFunc(masm);
586 __ dmfc1(v0, f2); 594 __ dmfc1(v0, f2);
587 __ jr(ra); 595 __ jr(ra);
588 __ nop(); 596 __ nop();
589 597
590 CodeDesc desc; 598 CodeDesc desc;
591 assm.GetCode(&desc); 599 assm.GetCode(&desc);
592 Handle<Code> code = isolate->factory()->NewCode( 600 Handle<Code> code = isolate->factory()->NewCode(
593 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 601 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
594 602
595 F_CVT f = FUNCTION_CAST<F_CVT>(code->entry()); 603 F_CVT f = FUNCTION_CAST<F_CVT>(code->entry());
596 604
597 return reinterpret_cast<RET_TYPE>( 605 return reinterpret_cast<RET_TYPE>(
598 CALL_GENERATED_CODE(isolate, f, x, 0, 0, 0, 0)); 606 CALL_GENERATED_CODE(isolate, f, x, 0, 0, 0, 0));
599 } 607 }
600 608
601 TEST(Cvt_s_uw_Trunc_uw_s) { 609 TEST(Cvt_s_uw_Trunc_uw_s) {
602 CcTest::InitializeVM(); 610 CcTest::InitializeVM();
603 FOR_UINT32_INPUTS(i) { 611 FOR_UINT32_INPUTS(i, cvt_trunc_uint32_test_values) {
604 uint32_t input = *i; 612 uint32_t input = *i;
605 CHECK_EQ(static_cast<float>(input), 613 CHECK_EQ(static_cast<float>(input),
606 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { 614 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
607 __ Cvt_s_uw(f0, a0); 615 __ Cvt_s_uw(f0, a0);
608 __ mthc1(zero_reg, f2); 616 __ mthc1(zero_reg, f2);
609 __ Trunc_uw_s(f2, f0, f1); 617 __ Trunc_uw_s(f2, f0, f1);
610 })); 618 }));
611 } 619 }
612 } 620 }
613 621
614 TEST(Cvt_s_ul_Trunc_ul_s) { 622 TEST(Cvt_s_ul_Trunc_ul_s) {
615 CcTest::InitializeVM(); 623 CcTest::InitializeVM();
616 FOR_UINT64_INPUTS(i) { 624 FOR_UINT64_INPUTS(i, cvt_trunc_uint64_test_values) {
617 uint64_t input = *i; 625 uint64_t input = *i;
618 CHECK_EQ(static_cast<float>(input), 626 CHECK_EQ(static_cast<float>(input),
619 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { 627 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
620 __ Cvt_s_ul(f0, a0); 628 __ Cvt_s_ul(f0, a0);
621 __ Trunc_ul_s(f2, f0, f1, v0); 629 __ Trunc_ul_s(f2, f0, f1, v0);
622 })); 630 }));
623 } 631 }
624 } 632 }
625 633
626 TEST(Cvt_d_ul_Trunc_ul_d) { 634 TEST(Cvt_d_ul_Trunc_ul_d) {
627 CcTest::InitializeVM(); 635 CcTest::InitializeVM();
628 FOR_UINT64_INPUTS(i) { 636 FOR_UINT64_INPUTS(i, cvt_trunc_uint64_test_values) {
629 uint64_t input = *i; 637 uint64_t input = *i;
630 CHECK_EQ(static_cast<double>(input), 638 CHECK_EQ(static_cast<double>(input),
631 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { 639 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
632 __ Cvt_d_ul(f0, a0); 640 __ Cvt_d_ul(f0, a0);
633 __ Trunc_ul_d(f2, f0, f1, v0); 641 __ Trunc_ul_d(f2, f0, f1, v0);
634 })); 642 }));
635 } 643 }
636 } 644 }
637 645
638 TEST(cvt_d_l_Trunc_l_d) { 646 TEST(cvt_d_l_Trunc_l_d) {
639 CcTest::InitializeVM(); 647 CcTest::InitializeVM();
640 FOR_INT64_INPUTS(i) { 648 FOR_INT64_INPUTS(i, cvt_trunc_int64_test_values) {
641 int64_t input = *i; 649 int64_t input = *i;
642 CHECK_EQ(static_cast<double>(input), 650 CHECK_EQ(static_cast<double>(input),
643 run_Cvt<int64_t>(input, [](MacroAssembler* masm) { 651 run_Cvt<int64_t>(input, [](MacroAssembler* masm) {
644 __ dmtc1(a0, f4); 652 __ dmtc1(a0, f4);
645 __ cvt_d_l(f0, f4); 653 __ cvt_d_l(f0, f4);
646 __ Trunc_l_d(f2, f0); 654 __ Trunc_l_d(f2, f0);
647 })); 655 }));
648 } 656 }
649 } 657 }
650 658
651 TEST(cvt_d_l_Trunc_l_ud) { 659 TEST(cvt_d_l_Trunc_l_ud) {
652 CcTest::InitializeVM(); 660 CcTest::InitializeVM();
653 FOR_INT64_INPUTS(i) { 661 FOR_INT64_INPUTS(i, cvt_trunc_int64_test_values) {
654 int64_t input = *i; 662 int64_t input = *i;
655 uint64_t abs_input = (input < 0) ? -input : input; 663 uint64_t abs_input = (input < 0) ? -input : input;
656 CHECK_EQ(static_cast<double>(abs_input), 664 CHECK_EQ(static_cast<double>(abs_input),
657 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) { 665 run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
658 __ dmtc1(a0, f4); 666 __ dmtc1(a0, f4);
659 __ cvt_d_l(f0, f4); 667 __ cvt_d_l(f0, f4);
660 __ Trunc_l_ud(f2, f0, f6); 668 __ Trunc_l_ud(f2, f0, f6);
661 })); 669 }));
662 } 670 }
663 } 671 }
664 672
665 TEST(cvt_d_w_Trunc_w_d) { 673 TEST(cvt_d_w_Trunc_w_d) {
666 CcTest::InitializeVM(); 674 CcTest::InitializeVM();
667 FOR_INT32_INPUTS(i) { 675 FOR_INT32_INPUTS(i, cvt_trunc_int32_test_values) {
668 int32_t input = *i; 676 int32_t input = *i;
669 CHECK_EQ(static_cast<double>(input), 677 CHECK_EQ(static_cast<double>(input),
670 run_Cvt<int64_t>(input, [](MacroAssembler* masm) { 678 run_Cvt<int64_t>(input, [](MacroAssembler* masm) {
671 __ mtc1(a0, f4); 679 __ mtc1(a0, f4);
672 __ cvt_d_w(f0, f4); 680 __ cvt_d_w(f0, f4);
673 __ Trunc_w_d(f2, f0); 681 __ Trunc_w_d(f2, f0);
674 __ mfc1(v1, f2); 682 __ mfc1(v1, f2);
675 __ dmtc1(v1, f2); 683 __ dmtc1(v1, f2);
676 })); 684 }));
677 } 685 }
678 } 686 }
679 687
688 static const std::vector<int32_t> overflow_int32_test_values() {
689 static const int32_t kValues[] = {
690 static_cast<int32_t>(0xf0000000), static_cast<int32_t>(0x00000001),
691 static_cast<int32_t>(0xff000000), static_cast<int32_t>(0x0000f000),
692 static_cast<int32_t>(0x0f000000), static_cast<int32_t>(0x991234ab),
693 static_cast<int32_t>(0xb0ffff01), static_cast<int32_t>(0x00006fff),
694 static_cast<int32_t>(0xffffffff)};
695 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]);
696 }
697
698 static const std::vector<int64_t> overflow_int64_test_values() {
699 static const int64_t kValues[] = {static_cast<int64_t>(0xf000000000000000),
700 static_cast<int64_t>(0x0000000000000001),
701 static_cast<int64_t>(0xff00000000000000),
702 static_cast<int64_t>(0x0000f00111111110),
703 static_cast<int64_t>(0x0f00001000000000),
704 static_cast<int64_t>(0x991234ab12a96731),
705 static_cast<int64_t>(0xb0ffff0f0f0f0f01),
706 static_cast<int64_t>(0x00006fffffffffff),
707 static_cast<int64_t>(0xffffffffffffffff)};
708 return std::vector<int64_t>(&kValues[0], &kValues[arraysize(kValues)]);
709 }
710
711 enum OverflowBranchType {
712 kAddBranchOverflow,
713 kSubBranchOverflow,
714 };
715
716 struct OverflowRegisterCombination {
717 Register dst;
718 Register left;
719 Register right;
720 Register scratch;
721 };
722
723 static const std::vector<enum OverflowBranchType> overflow_branch_type() {
724 static const enum OverflowBranchType kValues[] = {kAddBranchOverflow,
725 kSubBranchOverflow};
726 return std::vector<enum OverflowBranchType>(&kValues[0],
727 &kValues[arraysize(kValues)]);
728 }
729
730 static const std::vector<struct OverflowRegisterCombination>
731 overflow_register_combination() {
732 static const struct OverflowRegisterCombination kValues[] = {
733 {t0, t1, t2, t3}, {t0, t0, t2, t3}, {t0, t1, t0, t3}, {t0, t1, t1, t3}};
734 return std::vector<struct OverflowRegisterCombination>(
735 &kValues[0], &kValues[arraysize(kValues)]);
736 }
737
738 template <typename T>
739 static bool IsAddOverflow(T x, T y) {
740 DCHECK(std::numeric_limits<T>::is_integer);
741 T max = std::numeric_limits<T>::max();
742 T min = std::numeric_limits<T>::min();
743
744 return (x > 0 && y > (max - x)) || (x < 0 && y < (min - x));
745 }
746
747 template <typename T>
748 static bool IsSubOverflow(T x, T y) {
749 DCHECK(std::numeric_limits<T>::is_integer);
750 T max = std::numeric_limits<T>::max();
751 T min = std::numeric_limits<T>::min();
752
753 return (y > 0 && x < (min + y)) || (y < 0 && x > (max + y));
754 }
755
756 template <typename IN_TYPE, typename Func>
757 static bool runOverflow(IN_TYPE valLeft, IN_TYPE valRight,
758 Func GenerateOverflowInstructions) {
759 typedef int64_t (*F_CVT)(char* x0, int x1, int x2, int x3, int x4);
760
761 Isolate* isolate = CcTest::i_isolate();
762 HandleScope scope(isolate);
763 MacroAssembler assm(isolate, nullptr, 0,
764 v8::internal::CodeObjectRequired::kYes);
765 MacroAssembler* masm = &assm;
766
767 GenerateOverflowInstructions(masm, valLeft, valRight);
768 __ jr(ra);
769 __ nop();
770
771 CodeDesc desc;
772 assm.GetCode(&desc);
773 Handle<Code> code = isolate->factory()->NewCode(
774 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
775
776 F_CVT f = FUNCTION_CAST<F_CVT>(code->entry());
777
778 int64_t r =
779 reinterpret_cast<int64_t>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
780
781 DCHECK(r == 0 || r == 1);
782 return r;
783 }
784
785 TEST(BranchOverflowInt32BothLabels) {
786 FOR_INT32_INPUTS(i, overflow_int32_test_values) {
787 FOR_INT32_INPUTS(j, overflow_int32_test_values) {
788 FOR_ENUM_INPUTS(br, OverflowBranchType, overflow_branch_type) {
789 FOR_STRUCT_INPUTS(regComb, OverflowRegisterCombination,
790 overflow_register_combination) {
791 int32_t ii = *i;
792 int32_t jj = *j;
793 enum OverflowBranchType branchType = *br;
794 struct OverflowRegisterCombination rc = *regComb;
795
796 // If left and right register are same then left and right
797 // test values must also be same, otherwise we skip the test
798 if (rc.left.code() == rc.right.code()) {
799 if (ii != jj) {
800 continue;
801 }
802 }
803
804 bool res1 = runOverflow<int32_t>(
805 ii, jj, [branchType, rc](MacroAssembler* masm, int32_t valLeft,
806 int32_t valRight) {
807 Label overflow, no_overflow, end;
808 __ li(rc.left, valLeft);
809 __ li(rc.right, valRight);
810 switch (branchType) {
811 case kAddBranchOverflow:
812 __ AddBranchOvf(rc.dst, rc.left, rc.right, &overflow,
813 &no_overflow, rc.scratch);
814 break;
815 case kSubBranchOverflow:
816 __ SubBranchOvf(rc.dst, rc.left, rc.right, &overflow,
817 &no_overflow, rc.scratch);
818 break;
819 }
820 __ li(v0, 2);
821 __ Branch(&end);
822 __ bind(&overflow);
823 __ li(v0, 1);
824 __ Branch(&end);
825 __ bind(&no_overflow);
826 __ li(v0, 0);
827 __ bind(&end);
828 });
829
830 bool res2 = runOverflow<int32_t>(
831 ii, jj, [branchType, rc](MacroAssembler* masm, int32_t valLeft,
832 int32_t valRight) {
833 Label overflow, no_overflow, end;
834 __ li(rc.left, valLeft);
835 switch (branchType) {
836 case kAddBranchOverflow:
837 __ AddBranchOvf(rc.dst, rc.left, Operand(valRight),
838 &overflow, &no_overflow, rc.scratch);
839 break;
840 case kSubBranchOverflow:
841 __ SubBranchOvf(rc.dst, rc.left, Operand(valRight),
842 &overflow, &no_overflow, rc.scratch);
843 break;
844 }
845 __ li(v0, 2);
846 __ Branch(&end);
847 __ bind(&overflow);
848 __ li(v0, 1);
849 __ Branch(&end);
850 __ bind(&no_overflow);
851 __ li(v0, 0);
852 __ bind(&end);
853 });
854
855 switch (branchType) {
856 case kAddBranchOverflow:
857 CHECK_EQ(IsAddOverflow<int32_t>(ii, jj), res1);
858 CHECK_EQ(IsAddOverflow<int32_t>(ii, jj), res2);
859 break;
860 case kSubBranchOverflow:
861 CHECK_EQ(IsSubOverflow<int32_t>(ii, jj), res1);
862 CHECK_EQ(IsSubOverflow<int32_t>(ii, jj), res2);
863 break;
864 default:
865 UNREACHABLE();
866 }
867 }
868 }
869 }
870 }
871 }
872
873 TEST(BranchOverflowInt32LeftLabel) {
874 FOR_INT32_INPUTS(i, overflow_int32_test_values) {
875 FOR_INT32_INPUTS(j, overflow_int32_test_values) {
876 FOR_ENUM_INPUTS(br, OverflowBranchType, overflow_branch_type) {
877 FOR_STRUCT_INPUTS(regComb, OverflowRegisterCombination,
878 overflow_register_combination) {
879 int32_t ii = *i;
880 int32_t jj = *j;
881 enum OverflowBranchType branchType = *br;
882 struct OverflowRegisterCombination rc = *regComb;
883
884 // If left and right register are same then left and right
885 // test values must also be same, otherwise we skip the test
886 if (rc.left.code() == rc.right.code()) {
887 if (ii != jj) {
888 continue;
889 }
890 }
891
892 bool res1 = runOverflow<int32_t>(
893 ii, jj, [branchType, rc](MacroAssembler* masm, int32_t valLeft,
894 int32_t valRight) {
895 Label overflow, end;
896 __ li(rc.left, valLeft);
897 __ li(rc.right, valRight);
898 switch (branchType) {
899 case kAddBranchOverflow:
900 __ AddBranchOvf(rc.dst, rc.left, rc.right, &overflow, NULL,
901 rc.scratch);
902 break;
903 case kSubBranchOverflow:
904 __ SubBranchOvf(rc.dst, rc.left, rc.right, &overflow, NULL,
905 rc.scratch);
906 break;
907 }
908 __ li(v0, 0);
909 __ Branch(&end);
910 __ bind(&overflow);
911 __ li(v0, 1);
912 __ bind(&end);
913 });
914
915 bool res2 = runOverflow<int32_t>(
916 ii, jj, [branchType, rc](MacroAssembler* masm, int32_t valLeft,
917 int32_t valRight) {
918 Label overflow, end;
919 __ li(rc.left, valLeft);
920 switch (branchType) {
921 case kAddBranchOverflow:
922 __ AddBranchOvf(rc.dst, rc.left, Operand(valRight),
923 &overflow, NULL, rc.scratch);
924 break;
925 case kSubBranchOverflow:
926 __ SubBranchOvf(rc.dst, rc.left, Operand(valRight),
927 &overflow, NULL, rc.scratch);
928 break;
929 }
930 __ li(v0, 0);
931 __ Branch(&end);
932 __ bind(&overflow);
933 __ li(v0, 1);
934 __ bind(&end);
935 });
936
937 switch (branchType) {
938 case kAddBranchOverflow:
939 CHECK_EQ(IsAddOverflow<int32_t>(ii, jj), res1);
940 CHECK_EQ(IsAddOverflow<int32_t>(ii, jj), res2);
941 break;
942 case kSubBranchOverflow:
943 CHECK_EQ(IsSubOverflow<int32_t>(ii, jj), res1);
944 CHECK_EQ(IsSubOverflow<int32_t>(ii, jj), res2);
945 break;
946 default:
947 UNREACHABLE();
948 }
949 }
950 }
951 }
952 }
953 }
954
955 TEST(BranchOverflowInt32RightLabel) {
956 FOR_INT32_INPUTS(i, overflow_int32_test_values) {
957 FOR_INT32_INPUTS(j, overflow_int32_test_values) {
958 FOR_ENUM_INPUTS(br, OverflowBranchType, overflow_branch_type) {
959 FOR_STRUCT_INPUTS(regComb, OverflowRegisterCombination,
960 overflow_register_combination) {
961 int32_t ii = *i;
962 int32_t jj = *j;
963 enum OverflowBranchType branchType = *br;
964 struct OverflowRegisterCombination rc = *regComb;
965
966 // If left and right register are same then left and right
967 // test values must also be same, otherwise we skip the test
968 if (rc.left.code() == rc.right.code()) {
969 if (ii != jj) {
970 continue;
971 }
972 }
973
974 bool res1 = runOverflow<int32_t>(
975 ii, jj, [branchType, rc](MacroAssembler* masm, int32_t valLeft,
976 int32_t valRight) {
977 Label no_overflow, end;
978 __ li(rc.left, valLeft);
979 __ li(rc.right, valRight);
980 switch (branchType) {
981 case kAddBranchOverflow:
982 __ AddBranchOvf(rc.dst, rc.left, rc.right, NULL,
983 &no_overflow, rc.scratch);
984 break;
985 case kSubBranchOverflow:
986 __ SubBranchOvf(rc.dst, rc.left, rc.right, NULL,
987 &no_overflow, rc.scratch);
988 break;
989 }
990 __ li(v0, 1);
991 __ Branch(&end);
992 __ bind(&no_overflow);
993 __ li(v0, 0);
994 __ bind(&end);
995 });
996
997 bool res2 = runOverflow<int32_t>(
998 ii, jj, [branchType, rc](MacroAssembler* masm, int32_t valLeft,
999 int32_t valRight) {
1000 Label no_overflow, end;
1001 __ li(rc.left, valLeft);
1002 switch (branchType) {
1003 case kAddBranchOverflow:
1004 __ AddBranchOvf(rc.dst, rc.left, Operand(valRight), NULL,
1005 &no_overflow, rc.scratch);
1006 break;
1007 case kSubBranchOverflow:
1008 __ SubBranchOvf(rc.dst, rc.left, Operand(valRight), NULL,
1009 &no_overflow, rc.scratch);
1010 break;
1011 }
1012 __ li(v0, 1);
1013 __ Branch(&end);
1014 __ bind(&no_overflow);
1015 __ li(v0, 0);
1016 __ bind(&end);
1017 });
1018
1019 switch (branchType) {
1020 case kAddBranchOverflow:
1021 CHECK_EQ(IsAddOverflow<int32_t>(ii, jj), res1);
1022 CHECK_EQ(IsAddOverflow<int32_t>(ii, jj), res2);
1023 break;
1024 case kSubBranchOverflow:
1025 CHECK_EQ(IsSubOverflow<int32_t>(ii, jj), res1);
1026 CHECK_EQ(IsSubOverflow<int32_t>(ii, jj), res2);
1027 break;
1028 default:
1029 UNREACHABLE();
1030 }
1031 }
1032 }
1033 }
1034 }
1035 }
1036
1037 TEST(BranchOverflowInt64BothLabels) {
1038 FOR_INT64_INPUTS(i, overflow_int64_test_values) {
1039 FOR_INT64_INPUTS(j, overflow_int64_test_values) {
1040 FOR_ENUM_INPUTS(br, OverflowBranchType, overflow_branch_type) {
1041 FOR_STRUCT_INPUTS(regComb, OverflowRegisterCombination,
1042 overflow_register_combination) {
1043 int64_t ii = *i;
1044 int64_t jj = *j;
1045 enum OverflowBranchType branchType = *br;
1046 struct OverflowRegisterCombination rc = *regComb;
1047
1048 // If left and right register are same then left and right
1049 // test values must also be same, otherwise we skip the test
1050 if (rc.left.code() == rc.right.code()) {
1051 if (ii != jj) {
1052 continue;
1053 }
1054 }
1055
1056 bool res1 = runOverflow<int64_t>(
1057 ii, jj, [branchType, rc](MacroAssembler* masm, int64_t valLeft,
1058 int64_t valRight) {
1059 Label overflow, no_overflow, end;
1060 __ li(rc.left, valLeft);
1061 __ li(rc.right, valRight);
1062 switch (branchType) {
1063 case kAddBranchOverflow:
1064 __ DaddBranchOvf(rc.dst, rc.left, rc.right, &overflow,
1065 &no_overflow, rc.scratch);
1066 break;
1067 case kSubBranchOverflow:
1068 __ DsubBranchOvf(rc.dst, rc.left, rc.right, &overflow,
1069 &no_overflow, rc.scratch);
1070 break;
1071 }
1072 __ li(v0, 2);
1073 __ Branch(&end);
1074 __ bind(&overflow);
1075 __ li(v0, 1);
1076 __ Branch(&end);
1077 __ bind(&no_overflow);
1078 __ li(v0, 0);
1079 __ bind(&end);
1080 });
1081
1082 bool res2 = runOverflow<int64_t>(
1083 ii, jj, [branchType, rc](MacroAssembler* masm, int64_t valLeft,
1084 int64_t valRight) {
1085 Label overflow, no_overflow, end;
1086 __ li(rc.left, valLeft);
1087 switch (branchType) {
1088 case kAddBranchOverflow:
1089 __ DaddBranchOvf(rc.dst, rc.left, Operand(valRight),
1090 &overflow, &no_overflow, rc.scratch);
1091 break;
1092 case kSubBranchOverflow:
1093 __ DsubBranchOvf(rc.dst, rc.left, Operand(valRight),
1094 &overflow, &no_overflow, rc.scratch);
1095 break;
1096 }
1097 __ li(v0, 2);
1098 __ Branch(&end);
1099 __ bind(&overflow);
1100 __ li(v0, 1);
1101 __ Branch(&end);
1102 __ bind(&no_overflow);
1103 __ li(v0, 0);
1104 __ bind(&end);
1105 });
1106
1107 switch (branchType) {
1108 case kAddBranchOverflow:
1109 CHECK_EQ(IsAddOverflow<int64_t>(ii, jj), res1);
1110 CHECK_EQ(IsAddOverflow<int64_t>(ii, jj), res2);
1111 break;
1112 case kSubBranchOverflow:
1113 CHECK_EQ(IsSubOverflow<int64_t>(ii, jj), res1);
1114 CHECK_EQ(IsSubOverflow<int64_t>(ii, jj), res2);
1115 break;
1116 default:
1117 UNREACHABLE();
1118 }
1119 }
1120 }
1121 }
1122 }
1123 }
1124
1125 TEST(BranchOverflowInt64LeftLabel) {
1126 FOR_INT64_INPUTS(i, overflow_int64_test_values) {
1127 FOR_INT64_INPUTS(j, overflow_int64_test_values) {
1128 FOR_ENUM_INPUTS(br, OverflowBranchType, overflow_branch_type) {
1129 FOR_STRUCT_INPUTS(regComb, OverflowRegisterCombination,
1130 overflow_register_combination) {
1131 int64_t ii = *i;
1132 int64_t jj = *j;
1133 enum OverflowBranchType branchType = *br;
1134 struct OverflowRegisterCombination rc = *regComb;
1135
1136 // If left and right register are same then left and right
1137 // test values must also be same, otherwise we skip the test
1138 if (rc.left.code() == rc.right.code()) {
1139 if (ii != jj) {
1140 continue;
1141 }
1142 }
1143
1144 bool res1 = runOverflow<int64_t>(
1145 ii, jj, [branchType, rc](MacroAssembler* masm, int64_t valLeft,
1146 int64_t valRight) {
1147 Label overflow, end;
1148 __ li(rc.left, valLeft);
1149 __ li(rc.right, valRight);
1150 switch (branchType) {
1151 case kAddBranchOverflow:
1152 __ DaddBranchOvf(rc.dst, rc.left, rc.right, &overflow, NULL,
1153 rc.scratch);
1154 break;
1155 case kSubBranchOverflow:
1156 __ DsubBranchOvf(rc.dst, rc.left, rc.right, &overflow, NULL,
1157 rc.scratch);
1158 break;
1159 }
1160 __ li(v0, 0);
1161 __ Branch(&end);
1162 __ bind(&overflow);
1163 __ li(v0, 1);
1164 __ bind(&end);
1165 });
1166
1167 bool res2 = runOverflow<int64_t>(
1168 ii, jj, [branchType, rc](MacroAssembler* masm, int64_t valLeft,
1169 int64_t valRight) {
1170 Label overflow, end;
1171 __ li(rc.left, valLeft);
1172 switch (branchType) {
1173 case kAddBranchOverflow:
1174 __ DaddBranchOvf(rc.dst, rc.left, Operand(valRight),
1175 &overflow, NULL, rc.scratch);
1176 break;
1177 case kSubBranchOverflow:
1178 __ DsubBranchOvf(rc.dst, rc.left, Operand(valRight),
1179 &overflow, NULL, rc.scratch);
1180 break;
1181 }
1182 __ li(v0, 0);
1183 __ Branch(&end);
1184 __ bind(&overflow);
1185 __ li(v0, 1);
1186 __ bind(&end);
1187 });
1188
1189 switch (branchType) {
1190 case kAddBranchOverflow:
1191 CHECK_EQ(IsAddOverflow<int64_t>(ii, jj), res1);
1192 CHECK_EQ(IsAddOverflow<int64_t>(ii, jj), res2);
1193 break;
1194 case kSubBranchOverflow:
1195 CHECK_EQ(IsSubOverflow<int64_t>(ii, jj), res1);
1196 CHECK_EQ(IsSubOverflow<int64_t>(ii, jj), res2);
1197 break;
1198 default:
1199 UNREACHABLE();
1200 }
1201 }
1202 }
1203 }
1204 }
1205 }
1206
1207 TEST(BranchOverflowInt64RightLabel) {
1208 FOR_INT64_INPUTS(i, overflow_int64_test_values) {
1209 FOR_INT64_INPUTS(j, overflow_int64_test_values) {
1210 FOR_ENUM_INPUTS(br, OverflowBranchType, overflow_branch_type) {
1211 FOR_STRUCT_INPUTS(regComb, OverflowRegisterCombination,
1212 overflow_register_combination) {
1213 int64_t ii = *i;
1214 int64_t jj = *j;
1215 enum OverflowBranchType branchType = *br;
1216 struct OverflowRegisterCombination rc = *regComb;
1217
1218 // If left and right register are same then left and right
1219 // test values must also be same, otherwise we skip the test
1220 if (rc.left.code() == rc.right.code()) {
1221 if (ii != jj) {
1222 continue;
1223 }
1224 }
1225
1226 bool res1 = runOverflow<int64_t>(
1227 ii, jj, [branchType, rc](MacroAssembler* masm, int64_t valLeft,
1228 int64_t valRight) {
1229 Label no_overflow, end;
1230 __ li(rc.left, valLeft);
1231 __ li(rc.right, valRight);
1232 switch (branchType) {
1233 case kAddBranchOverflow:
1234 __ DaddBranchOvf(rc.dst, rc.left, rc.right, NULL,
1235 &no_overflow, rc.scratch);
1236 break;
1237 case kSubBranchOverflow:
1238 __ DsubBranchOvf(rc.dst, rc.left, rc.right, NULL,
1239 &no_overflow, rc.scratch);
1240 break;
1241 }
1242 __ li(v0, 1);
1243 __ Branch(&end);
1244 __ bind(&no_overflow);
1245 __ li(v0, 0);
1246 __ bind(&end);
1247 });
1248
1249 bool res2 = runOverflow<int64_t>(
1250 ii, jj, [branchType, rc](MacroAssembler* masm, int64_t valLeft,
1251 int64_t valRight) {
1252 Label no_overflow, end;
1253 __ li(rc.left, valLeft);
1254 switch (branchType) {
1255 case kAddBranchOverflow:
1256 __ DaddBranchOvf(rc.dst, rc.left, Operand(valRight), NULL,
1257 &no_overflow, rc.scratch);
1258 break;
1259 case kSubBranchOverflow:
1260 __ DsubBranchOvf(rc.dst, rc.left, Operand(valRight), NULL,
1261 &no_overflow, rc.scratch);
1262 break;
1263 }
1264 __ li(v0, 1);
1265 __ Branch(&end);
1266 __ bind(&no_overflow);
1267 __ li(v0, 0);
1268 __ bind(&end);
1269 });
1270
1271 switch (branchType) {
1272 case kAddBranchOverflow:
1273 CHECK_EQ(IsAddOverflow<int64_t>(ii, jj), res1);
1274 CHECK_EQ(IsAddOverflow<int64_t>(ii, jj), res2);
1275 break;
1276 case kSubBranchOverflow:
1277 CHECK_EQ(IsSubOverflow<int64_t>(ii, jj), res1);
1278 CHECK_EQ(IsSubOverflow<int64_t>(ii, jj), res2);
1279 break;
1280 default:
1281 UNREACHABLE();
1282 }
1283 }
1284 }
1285 }
1286 }
1287 }
1288
680 TEST(min_max_nan) { 1289 TEST(min_max_nan) {
681 CcTest::InitializeVM(); 1290 CcTest::InitializeVM();
682 Isolate* isolate = CcTest::i_isolate(); 1291 Isolate* isolate = CcTest::i_isolate();
683 HandleScope scope(isolate); 1292 HandleScope scope(isolate);
684 MacroAssembler assembler(isolate, nullptr, 0, 1293 MacroAssembler assembler(isolate, nullptr, 0,
685 v8::internal::CodeObjectRequired::kYes); 1294 v8::internal::CodeObjectRequired::kYes);
686 MacroAssembler* masm = &assembler; 1295 MacroAssembler* masm = &assembler;
687 1296
688 struct TestFloat { 1297 struct TestFloat {
689 double a; 1298 double a;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0); 1390 CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0);
782 1391
783 CHECK_EQ(0, memcmp(&test.c, &outputsdmin[i], sizeof(test.c))); 1392 CHECK_EQ(0, memcmp(&test.c, &outputsdmin[i], sizeof(test.c)));
784 CHECK_EQ(0, memcmp(&test.d, &outputsdmax[i], sizeof(test.d))); 1393 CHECK_EQ(0, memcmp(&test.d, &outputsdmax[i], sizeof(test.d)));
785 CHECK_EQ(0, memcmp(&test.g, &outputsfmin[i], sizeof(test.g))); 1394 CHECK_EQ(0, memcmp(&test.g, &outputsfmin[i], sizeof(test.g)));
786 CHECK_EQ(0, memcmp(&test.h, &outputsfmax[i], sizeof(test.h))); 1395 CHECK_EQ(0, memcmp(&test.h, &outputsfmax[i], sizeof(test.h)));
787 } 1396 }
788 } 1397 }
789 1398
790 #undef __ 1399 #undef __
OLDNEW
« no previous file with comments | « test/cctest/test-macro-assembler-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698