Changeset 258038 in webkit
- Timestamp:
- Mar 6, 2020, 5:16:14 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r257908 r258038 1 2020-03-06 Mark Lam <mark.lam@apple.com> 2 3 Fix some issues in the ARM64 moveConditionallyAfterFloatingPointCompare() and moveDoubleConditionallyAfterFloatingPointCompare(). 4 https://bugs.webkit.org/show_bug.cgi?id=208731 5 <rdar://problem/59222568> 6 7 Reviewed by Saam Barati. 8 9 Both the ARM64 moveConditionallyAfterFloatingPointCompare() and 10 moveDoubleConditionallyAfterFloatingPointCompare() had the following issues: 11 12 1. For the DoubleNotEqual condition, they fail to set the result register if 13 one or both of the comparison operands is a NaN. 14 15 2. For the DoubleEqualOrUnordered condition, they can clobber the else case 16 input register if one of the comparison operands is a NaN. 17 18 This patch fixes both of these, and exhaustive testmasm test cases for affected 19 MacroAssembler instruction emitters using these functions. 20 21 * assembler/MacroAssemblerARM64.h: 22 (JSC::MacroAssemblerARM64::moveConditionallyAfterFloatingPointCompare): 23 (JSC::MacroAssemblerARM64::moveDoubleConditionallyAfterFloatingPointCompare): 24 * assembler/testmasm.cpp: 25 (JSC::testCompareDouble): 26 (JSC::testCompareDoubleSameArg): 27 (JSC::testMoveConditionallyFloatingPoint): 28 (JSC::testMoveConditionallyDouble2): 29 (JSC::testMoveConditionallyDouble3): 30 (JSC::testMoveConditionallyDouble3DestSameAsThenCase): 31 (JSC::testMoveConditionallyDouble3DestSameAsElseCase): 32 (JSC::testMoveConditionallyFloat2): 33 (JSC::testMoveConditionallyFloat3): 34 (JSC::testMoveConditionallyFloat3DestSameAsThenCase): 35 (JSC::testMoveConditionallyFloat3DestSameAsElseCase): 36 (JSC::testMoveDoubleConditionallyDouble): 37 (JSC::testMoveDoubleConditionallyDoubleDestSameAsThenCase): 38 (JSC::testMoveDoubleConditionallyDoubleDestSameAsElseCase): 39 (JSC::testMoveDoubleConditionallyFloat): 40 (JSC::testMoveDoubleConditionallyFloatDestSameAsThenCase): 41 (JSC::testMoveDoubleConditionallyFloatDestSameAsElseCase): 42 (JSC::testMoveConditionallyFloatingPointSameArg): 43 (JSC::testMoveConditionallyDouble2SameArg): 44 (JSC::testMoveConditionallyDouble3SameArg): 45 (JSC::testMoveConditionallyFloat2SameArg): 46 (JSC::testMoveConditionallyFloat3SameArg): 47 (JSC::testMoveDoubleConditionallyDoubleSameArg): 48 (JSC::testMoveDoubleConditionallyFloatSameArg): 49 (JSC::run): 50 1 51 2020-03-05 Paulo Matos <pmatos@igalia.com> 2 52 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r252728 r258038 2029 2029 { 2030 2030 if (cond == DoubleNotEqual) { 2031 Jump unordered = makeBranch(Assembler::ConditionVS); 2032 m_assembler.csel<datasize>(dest, thenCase, elseCase, Assembler::ConditionNE); 2033 unordered.link(this); 2031 if (dest == thenCase) { 2032 // If the compare is unordered, elseCase is copied to thenCase and the 2033 // next csel has all arguments equal to elseCase. 2034 // If the compare is ordered, dest is unchanged and NE decides 2035 // what value to set. 2036 m_assembler.csel<datasize>(thenCase, elseCase, thenCase, Assembler::ConditionNE); 2037 m_assembler.csel<datasize>(dest, thenCase, elseCase, Assembler::ConditionNE); 2038 } else { 2039 move(elseCase, dest); 2040 Jump unordered = makeBranch(Assembler::ConditionVS); 2041 m_assembler.csel<datasize>(dest, thenCase, elseCase, Assembler::ConditionNE); 2042 unordered.link(this); 2043 } 2034 2044 return; 2035 2045 } 2036 2046 if (cond == DoubleEqualOrUnordered) { 2037 // If the compare is unordered, thenCase is copied to elseCase and the 2038 // next csel has all arguments equal to thenCase. 2039 // If the compare is ordered, dest is unchanged and EQ decides 2040 // what value to set. 2041 m_assembler.csel<datasize>(elseCase, thenCase, elseCase, Assembler::ConditionVS); 2042 m_assembler.csel<datasize>(dest, thenCase, elseCase, Assembler::ConditionEQ); 2047 if (dest == elseCase) { 2048 // If the compare is unordered, thenCase is copied to elseCase and the 2049 // next csel has all arguments equal to thenCase. 2050 // If the compare is ordered, dest is unchanged and EQ decides 2051 // what value to set. 2052 m_assembler.csel<datasize>(elseCase, thenCase, elseCase, Assembler::ConditionVS); 2053 m_assembler.csel<datasize>(dest, thenCase, elseCase, Assembler::ConditionEQ); 2054 } else { 2055 move(thenCase, dest); 2056 Jump unordered = makeBranch(Assembler::ConditionVS); 2057 m_assembler.csel<datasize>(dest, thenCase, elseCase, Assembler::ConditionEQ); 2058 unordered.link(this); 2059 } 2043 2060 return; 2044 2061 } … … 2050 2067 { 2051 2068 if (cond == DoubleNotEqual) { 2052 Jump unordered = makeBranch(Assembler::ConditionVS); 2053 m_assembler.fcsel<datasize>(dest, thenCase, elseCase, Assembler::ConditionNE); 2054 unordered.link(this); 2069 if (dest == thenCase) { 2070 // If the compare is unordered, elseCase is copied to thenCase and the 2071 // next fcsel has all arguments equal to elseCase. 2072 // If the compare is ordered, dest is unchanged and NE decides 2073 // what value to set. 2074 m_assembler.fcsel<datasize>(thenCase, elseCase, thenCase, Assembler::ConditionVS); 2075 m_assembler.fcsel<datasize>(dest, thenCase, elseCase, Assembler::ConditionNE); 2076 } else { 2077 m_assembler.fmov<64>(dest, elseCase); 2078 Jump unordered = makeBranch(Assembler::ConditionVS); 2079 m_assembler.fcsel<datasize>(dest, thenCase, elseCase, Assembler::ConditionNE); 2080 unordered.link(this); 2081 } 2055 2082 return; 2056 2083 } 2057 2084 if (cond == DoubleEqualOrUnordered) { 2058 // If the compare is unordered, thenCase is copied to elseCase and the 2059 // next csel has all arguments equal to thenCase. 2060 // If the compare is ordered, dest is unchanged and EQ decides 2061 // what value to set. 2062 m_assembler.fcsel<datasize>(elseCase, thenCase, elseCase, Assembler::ConditionVS); 2063 m_assembler.fcsel<datasize>(dest, thenCase, elseCase, Assembler::ConditionEQ); 2085 if (dest == elseCase) { 2086 // If the compare is unordered, thenCase is copied to elseCase and the 2087 // next csel has all arguments equal to thenCase. 2088 // If the compare is ordered, dest is unchanged and EQ decides 2089 // what value to set. 2090 m_assembler.fcsel<datasize>(elseCase, thenCase, elseCase, Assembler::ConditionVS); 2091 m_assembler.fcsel<datasize>(dest, thenCase, elseCase, Assembler::ConditionEQ); 2092 } else { 2093 m_assembler.fmov<64>(dest, thenCase); 2094 Jump unordered = makeBranch(Assembler::ConditionVS); 2095 m_assembler.fcsel<datasize>(dest, thenCase, elseCase, Assembler::ConditionEQ); 2096 unordered.link(this); 2097 } 2064 2098 return; 2065 2099 } -
trunk/Source/JavaScriptCore/assembler/testmasm.cpp
r252728 r258038 500 500 }); 501 501 502 auto expectedResult = [&, condition] (double a, double b) -> int { 503 auto isUnordered = [] (double x) { 504 return x != x; 505 }; 506 switch (condition) { 507 case MacroAssembler::DoubleEqual: 508 return !isUnordered(a) && !isUnordered(b) && (a == b); 509 case MacroAssembler::DoubleNotEqual: 510 return !isUnordered(a) && !isUnordered(b) && (a != b); 511 case MacroAssembler::DoubleGreaterThan: 512 return !isUnordered(a) && !isUnordered(b) && (a > b); 513 case MacroAssembler::DoubleGreaterThanOrEqual: 514 return !isUnordered(a) && !isUnordered(b) && (a >= b); 515 case MacroAssembler::DoubleLessThan: 516 return !isUnordered(a) && !isUnordered(b) && (a < b); 517 case MacroAssembler::DoubleLessThanOrEqual: 518 return !isUnordered(a) && !isUnordered(b) && (a <= b); 519 case MacroAssembler::DoubleEqualOrUnordered: 520 return isUnordered(a) || isUnordered(b) || (a == b); 521 case MacroAssembler::DoubleNotEqualOrUnordered: 522 return isUnordered(a) || isUnordered(b) || (a != b); 523 case MacroAssembler::DoubleGreaterThanOrUnordered: 524 return isUnordered(a) || isUnordered(b) || (a > b); 525 case MacroAssembler::DoubleGreaterThanOrEqualOrUnordered: 526 return isUnordered(a) || isUnordered(b) || (a >= b); 527 case MacroAssembler::DoubleLessThanOrUnordered: 528 return isUnordered(a) || isUnordered(b) || (a < b); 529 case MacroAssembler::DoubleLessThanOrEqualOrUnordered: 530 return isUnordered(a) || isUnordered(b) || (a <= b); 531 } // switch 532 }; 533 502 534 auto operands = doubleOperands(); 503 535 for (auto a : operands) { … … 505 537 arg1 = a; 506 538 arg2 = b; 507 CHECK_EQ(invoke<int>(compareDouble), invoke<int>(compareDoubleGeneric)); 539 CHECK_EQ(invoke<int>(compareDouble), expectedResult(a, b)); 540 CHECK_EQ(invoke<int>(compareDoubleGeneric), expectedResult(a, b)); 508 541 } 542 } 543 } 544 545 void testCompareDoubleSameArg(MacroAssembler::DoubleCondition condition) 546 { 547 double arg1 = 0; 548 549 auto compareDouble = compile([&, condition] (CCallHelpers& jit) { 550 emitFunctionPrologue(jit); 551 552 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 553 jit.move(CCallHelpers::TrustedImm32(-1), GPRInfo::returnValueGPR); 554 jit.compareDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, GPRInfo::returnValueGPR); 555 556 emitFunctionEpilogue(jit); 557 jit.ret(); 558 }); 559 560 auto compareDoubleGeneric = compile([&, condition] (CCallHelpers& jit) { 561 emitFunctionPrologue(jit); 562 563 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 564 jit.move(CCallHelpers::TrustedImm32(1), GPRInfo::returnValueGPR); 565 auto jump = jit.branchDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0); 566 jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::returnValueGPR); 567 jump.link(&jit); 568 569 emitFunctionEpilogue(jit); 570 jit.ret(); 571 }); 572 573 auto expectedResult = [&, condition] (double a) -> int { 574 auto isUnordered = [] (double x) { 575 return x != x; 576 }; 577 switch (condition) { 578 case MacroAssembler::DoubleEqual: 579 return !isUnordered(a) && (a == a); 580 case MacroAssembler::DoubleNotEqual: 581 return !isUnordered(a) && (a != a); 582 case MacroAssembler::DoubleGreaterThan: 583 return !isUnordered(a) && (a > a); 584 case MacroAssembler::DoubleGreaterThanOrEqual: 585 return !isUnordered(a) && (a >= a); 586 case MacroAssembler::DoubleLessThan: 587 return !isUnordered(a) && (a < a); 588 case MacroAssembler::DoubleLessThanOrEqual: 589 return !isUnordered(a) && (a <= a); 590 case MacroAssembler::DoubleEqualOrUnordered: 591 return isUnordered(a) || (a == a); 592 case MacroAssembler::DoubleNotEqualOrUnordered: 593 return isUnordered(a) || (a != a); 594 case MacroAssembler::DoubleGreaterThanOrUnordered: 595 return isUnordered(a) || (a > a); 596 case MacroAssembler::DoubleGreaterThanOrEqualOrUnordered: 597 return isUnordered(a) || (a >= a); 598 case MacroAssembler::DoubleLessThanOrUnordered: 599 return isUnordered(a) || (a < a); 600 case MacroAssembler::DoubleLessThanOrEqualOrUnordered: 601 return isUnordered(a) || (a <= a); 602 } // switch 603 }; 604 605 auto operands = doubleOperands(); 606 for (auto a : operands) { 607 arg1 = a; 608 CHECK_EQ(invoke<int>(compareDouble), expectedResult(a)); 609 CHECK_EQ(invoke<int>(compareDoubleGeneric), expectedResult(a)); 509 610 } 510 611 } … … 587 688 } 588 689 } 589 #endif 690 #endif // CPU(X86) || CPU(X86_64) || CPU(ARM64) 691 692 #if CPU(X86_64) || CPU(ARM64) 693 694 template<typename T, typename SelectionType> 695 void testMoveConditionallyFloatingPoint(MacroAssembler::DoubleCondition condition, const MacroAssemblerCodeRef<JSEntryPtrTag>& testCode, T& arg1, T& arg2, const Vector<T> operands, SelectionType selectionA, SelectionType selectionB) 696 { 697 auto expectedResult = [&, condition] (T a, T b) -> SelectionType { 698 auto isUnordered = [] (double x) { 699 return x != x; 700 }; 701 switch (condition) { 702 case MacroAssembler::DoubleEqual: 703 return !isUnordered(a) && !isUnordered(b) && (a == b) ? selectionA : selectionB; 704 case MacroAssembler::DoubleNotEqual: 705 return !isUnordered(a) && !isUnordered(b) && (a != b) ? selectionA : selectionB; 706 case MacroAssembler::DoubleGreaterThan: 707 return !isUnordered(a) && !isUnordered(b) && (a > b) ? selectionA : selectionB; 708 case MacroAssembler::DoubleGreaterThanOrEqual: 709 return !isUnordered(a) && !isUnordered(b) && (a >= b) ? selectionA : selectionB; 710 case MacroAssembler::DoubleLessThan: 711 return !isUnordered(a) && !isUnordered(b) && (a < b) ? selectionA : selectionB; 712 case MacroAssembler::DoubleLessThanOrEqual: 713 return !isUnordered(a) && !isUnordered(b) && (a <= b) ? selectionA : selectionB; 714 case MacroAssembler::DoubleEqualOrUnordered: 715 return isUnordered(a) || isUnordered(b) || (a == b) ? selectionA : selectionB; 716 case MacroAssembler::DoubleNotEqualOrUnordered: 717 return isUnordered(a) || isUnordered(b) || (a != b) ? selectionA : selectionB; 718 case MacroAssembler::DoubleGreaterThanOrUnordered: 719 return isUnordered(a) || isUnordered(b) || (a > b) ? selectionA : selectionB; 720 case MacroAssembler::DoubleGreaterThanOrEqualOrUnordered: 721 return isUnordered(a) || isUnordered(b) || (a >= b) ? selectionA : selectionB; 722 case MacroAssembler::DoubleLessThanOrUnordered: 723 return isUnordered(a) || isUnordered(b) || (a < b) ? selectionA : selectionB; 724 case MacroAssembler::DoubleLessThanOrEqualOrUnordered: 725 return isUnordered(a) || isUnordered(b) || (a <= b) ? selectionA : selectionB; 726 } // switch 727 }; 728 729 for (auto a : operands) { 730 for (auto b : operands) { 731 arg1 = a; 732 arg2 = b; 733 CHECK_EQ(invoke<SelectionType>(testCode), expectedResult(a, b)); 734 } 735 } 736 } 737 738 void testMoveConditionallyDouble2(MacroAssembler::DoubleCondition condition) 739 { 740 double arg1 = 0; 741 double arg2 = 0; 742 unsigned selectionA = 42; 743 unsigned selectionB = 17; 744 745 auto testCode = compile([&, condition] (CCallHelpers& jit) { 746 emitFunctionPrologue(jit); 747 748 GPRReg destGPR = GPRInfo::returnValueGPR; 749 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 750 RELEASE_ASSERT(destGPR != selectionAGPR); 751 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 752 jit.move(CCallHelpers::TrustedImm32(selectionB), destGPR); 753 754 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 755 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 756 jit.moveConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, destGPR); 757 758 emitFunctionEpilogue(jit); 759 jit.ret(); 760 }); 761 762 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 763 } 764 765 void testMoveConditionallyDouble3(MacroAssembler::DoubleCondition condition) 766 { 767 double arg1 = 0; 768 double arg2 = 0; 769 unsigned selectionA = 42; 770 unsigned selectionB = 17; 771 unsigned corruptedSelectionA = 0xbbad000a; 772 unsigned corruptedSelectionB = 0xbbad000b; 773 774 auto testCode = compile([&, condition] (CCallHelpers& jit) { 775 emitFunctionPrologue(jit); 776 777 GPRReg destGPR = GPRInfo::returnValueGPR; 778 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 779 GPRReg selectionBGPR = GPRInfo::argumentGPR3; 780 RELEASE_ASSERT(destGPR != selectionAGPR); 781 RELEASE_ASSERT(destGPR != selectionBGPR); 782 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 783 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 784 jit.move(CCallHelpers::TrustedImm32(-1), destGPR); 785 786 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 787 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 788 jit.moveConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, selectionBGPR, destGPR); 789 790 auto aIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionAGPR, CCallHelpers::TrustedImm32(selectionA)); 791 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionA), destGPR); 792 aIsUnchanged.link(&jit); 793 794 auto bIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionBGPR, CCallHelpers::TrustedImm32(selectionB)); 795 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionB), destGPR); 796 bIsUnchanged.link(&jit); 797 798 emitFunctionEpilogue(jit); 799 jit.ret(); 800 }); 801 802 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 803 } 804 805 void testMoveConditionallyDouble3DestSameAsThenCase(MacroAssembler::DoubleCondition condition) 806 { 807 double arg1 = 0; 808 double arg2 = 0; 809 unsigned selectionA = 42; 810 unsigned selectionB = 17; 811 unsigned corruptedSelectionB = 0xbbad000b; 812 813 auto testCode = compile([&, condition] (CCallHelpers& jit) { 814 emitFunctionPrologue(jit); 815 816 GPRReg destGPR = GPRInfo::returnValueGPR; 817 GPRReg selectionAGPR = destGPR; 818 GPRReg selectionBGPR = GPRInfo::argumentGPR3; 819 RELEASE_ASSERT(destGPR == selectionAGPR); 820 RELEASE_ASSERT(destGPR != selectionBGPR); 821 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 822 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 823 824 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 825 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 826 jit.moveConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, selectionBGPR, destGPR); 827 828 auto bIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionBGPR, CCallHelpers::TrustedImm32(selectionB)); 829 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionB), destGPR); 830 bIsUnchanged.link(&jit); 831 832 emitFunctionEpilogue(jit); 833 jit.ret(); 834 }); 835 836 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 837 } 838 839 void testMoveConditionallyDouble3DestSameAsElseCase(MacroAssembler::DoubleCondition condition) 840 { 841 double arg1 = 0; 842 double arg2 = 0; 843 unsigned selectionA = 42; 844 unsigned selectionB = 17; 845 unsigned corruptedSelectionA = 0xbbad000a; 846 847 auto testCode = compile([&, condition] (CCallHelpers& jit) { 848 emitFunctionPrologue(jit); 849 850 GPRReg destGPR = GPRInfo::returnValueGPR; 851 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 852 GPRReg selectionBGPR = destGPR; 853 RELEASE_ASSERT(destGPR != selectionAGPR); 854 RELEASE_ASSERT(destGPR == selectionBGPR); 855 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 856 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 857 858 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 859 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 860 jit.moveConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, selectionBGPR, destGPR); 861 862 auto aIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionAGPR, CCallHelpers::TrustedImm32(selectionA)); 863 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionA), destGPR); 864 aIsUnchanged.link(&jit); 865 866 emitFunctionEpilogue(jit); 867 jit.ret(); 868 }); 869 870 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 871 } 872 873 void testMoveConditionallyFloat2(MacroAssembler::DoubleCondition condition) 874 { 875 float arg1 = 0; 876 float arg2 = 0; 877 unsigned selectionA = 42; 878 unsigned selectionB = 17; 879 880 auto testCode = compile([&, condition] (CCallHelpers& jit) { 881 emitFunctionPrologue(jit); 882 883 GPRReg destGPR = GPRInfo::returnValueGPR; 884 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 885 RELEASE_ASSERT(destGPR != selectionAGPR); 886 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 887 jit.move(CCallHelpers::TrustedImm32(selectionB), GPRInfo::returnValueGPR); 888 889 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 890 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 891 jit.moveConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, destGPR); 892 893 emitFunctionEpilogue(jit); 894 jit.ret(); 895 }); 896 897 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 898 } 899 900 void testMoveConditionallyFloat3(MacroAssembler::DoubleCondition condition) 901 { 902 float arg1 = 0; 903 float arg2 = 0; 904 unsigned selectionA = 42; 905 unsigned selectionB = 17; 906 unsigned corruptedSelectionA = 0xbbad000a; 907 unsigned corruptedSelectionB = 0xbbad000b; 908 909 auto testCode = compile([&, condition] (CCallHelpers& jit) { 910 emitFunctionPrologue(jit); 911 912 GPRReg destGPR = GPRInfo::returnValueGPR; 913 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 914 GPRReg selectionBGPR = GPRInfo::argumentGPR3; 915 RELEASE_ASSERT(destGPR != selectionAGPR); 916 RELEASE_ASSERT(destGPR != selectionBGPR); 917 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 918 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 919 jit.move(CCallHelpers::TrustedImm32(-1), destGPR); 920 921 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 922 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 923 jit.moveConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, selectionBGPR, destGPR); 924 925 auto aIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionAGPR, CCallHelpers::TrustedImm32(selectionA)); 926 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionA), destGPR); 927 aIsUnchanged.link(&jit); 928 929 auto bIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionBGPR, CCallHelpers::TrustedImm32(selectionB)); 930 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionB), destGPR); 931 bIsUnchanged.link(&jit); 932 933 emitFunctionEpilogue(jit); 934 jit.ret(); 935 }); 936 937 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 938 } 939 940 void testMoveConditionallyFloat3DestSameAsThenCase(MacroAssembler::DoubleCondition condition) 941 { 942 float arg1 = 0; 943 float arg2 = 0; 944 unsigned selectionA = 42; 945 unsigned selectionB = 17; 946 unsigned corruptedSelectionB = 0xbbad000b; 947 948 auto testCode = compile([&, condition] (CCallHelpers& jit) { 949 emitFunctionPrologue(jit); 950 951 GPRReg destGPR = GPRInfo::returnValueGPR; 952 GPRReg selectionAGPR = destGPR; 953 GPRReg selectionBGPR = GPRInfo::argumentGPR3; 954 RELEASE_ASSERT(destGPR == selectionAGPR); 955 RELEASE_ASSERT(destGPR != selectionBGPR); 956 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 957 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 958 959 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 960 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 961 jit.moveConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, selectionBGPR, destGPR); 962 963 auto bIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionBGPR, CCallHelpers::TrustedImm32(selectionB)); 964 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionB), destGPR); 965 bIsUnchanged.link(&jit); 966 967 emitFunctionEpilogue(jit); 968 jit.ret(); 969 }); 970 971 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 972 } 973 974 void testMoveConditionallyFloat3DestSameAsElseCase(MacroAssembler::DoubleCondition condition) 975 { 976 float arg1 = 0; 977 float arg2 = 0; 978 unsigned selectionA = 42; 979 unsigned selectionB = 17; 980 unsigned corruptedSelectionA = 0xbbad000a; 981 982 auto testCode = compile([&, condition] (CCallHelpers& jit) { 983 emitFunctionPrologue(jit); 984 985 GPRReg destGPR = GPRInfo::returnValueGPR; 986 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 987 GPRReg selectionBGPR = destGPR; 988 RELEASE_ASSERT(destGPR != selectionAGPR); 989 RELEASE_ASSERT(destGPR == selectionBGPR); 990 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 991 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 992 993 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 994 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), FPRInfo::fpRegT1); 995 jit.moveConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1, selectionAGPR, selectionBGPR, destGPR); 996 997 auto aIsUnchanged = jit.branch32(CCallHelpers::Equal, selectionAGPR, CCallHelpers::TrustedImm32(selectionA)); 998 jit.move(CCallHelpers::TrustedImm32(corruptedSelectionA), destGPR); 999 aIsUnchanged.link(&jit); 1000 1001 emitFunctionEpilogue(jit); 1002 jit.ret(); 1003 }); 1004 1005 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 1006 } 1007 1008 void testMoveDoubleConditionallyDouble(MacroAssembler::DoubleCondition condition) 1009 { 1010 double arg1 = 0; 1011 double arg2 = 0; 1012 double selectionA = 42.0; 1013 double selectionB = 17.0; 1014 double corruptedSelectionA = 55555; 1015 double corruptedSelectionB = 66666; 1016 1017 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1018 emitFunctionPrologue(jit); 1019 1020 FPRReg destFPR = FPRInfo::returnValueFPR; 1021 FPRReg selectionAFPR = FPRInfo::fpRegT1; 1022 FPRReg selectionBFPR = FPRInfo::fpRegT2; 1023 FPRReg arg1FPR = FPRInfo::fpRegT3; 1024 FPRReg arg2FPR = FPRInfo::fpRegT4; 1025 1026 RELEASE_ASSERT(destFPR != selectionAFPR); 1027 RELEASE_ASSERT(destFPR != selectionBFPR); 1028 RELEASE_ASSERT(destFPR != arg1FPR); 1029 RELEASE_ASSERT(destFPR != arg2FPR); 1030 1031 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), arg1FPR); 1032 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), arg2FPR); 1033 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), selectionAFPR); 1034 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), selectionBFPR); 1035 jit.moveDoubleConditionallyDouble(condition, arg1FPR, arg2FPR, selectionAFPR, selectionBFPR, destFPR); 1036 1037 FPRReg tempFPR = FPRInfo::fpRegT5; 1038 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), tempFPR); 1039 auto aIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionAFPR, tempFPR); 1040 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionA), destFPR); 1041 aIsUnchanged.link(&jit); 1042 1043 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), tempFPR); 1044 auto bIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionBFPR, tempFPR); 1045 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionB), destFPR); 1046 bIsUnchanged.link(&jit); 1047 1048 emitFunctionEpilogue(jit); 1049 jit.ret(); 1050 }); 1051 1052 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 1053 } 1054 1055 void testMoveDoubleConditionallyDoubleDestSameAsThenCase(MacroAssembler::DoubleCondition condition) 1056 { 1057 double arg1 = 0; 1058 double arg2 = 0; 1059 double selectionA = 42.0; 1060 double selectionB = 17.0; 1061 double corruptedSelectionB = 66666; 1062 1063 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1064 emitFunctionPrologue(jit); 1065 1066 FPRReg destFPR = FPRInfo::returnValueFPR; 1067 FPRReg selectionAFPR = destFPR; 1068 FPRReg selectionBFPR = FPRInfo::fpRegT2; 1069 FPRReg arg1FPR = FPRInfo::fpRegT3; 1070 FPRReg arg2FPR = FPRInfo::fpRegT4; 1071 1072 RELEASE_ASSERT(destFPR == selectionAFPR); 1073 RELEASE_ASSERT(destFPR != selectionBFPR); 1074 RELEASE_ASSERT(destFPR != arg1FPR); 1075 RELEASE_ASSERT(destFPR != arg2FPR); 1076 1077 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), arg1FPR); 1078 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), arg2FPR); 1079 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), selectionAFPR); 1080 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), selectionBFPR); 1081 jit.moveDoubleConditionallyDouble(condition, arg1FPR, arg2FPR, selectionAFPR, selectionBFPR, destFPR); 1082 1083 FPRReg tempFPR = FPRInfo::fpRegT5; 1084 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), tempFPR); 1085 auto bIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionBFPR, tempFPR); 1086 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionB), destFPR); 1087 bIsUnchanged.link(&jit); 1088 1089 emitFunctionEpilogue(jit); 1090 jit.ret(); 1091 }); 1092 1093 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 1094 } 1095 1096 void testMoveDoubleConditionallyDoubleDestSameAsElseCase(MacroAssembler::DoubleCondition condition) 1097 { 1098 double arg1 = 0; 1099 double arg2 = 0; 1100 double selectionA = 42.0; 1101 double selectionB = 17.0; 1102 double corruptedSelectionA = 55555; 1103 1104 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1105 emitFunctionPrologue(jit); 1106 1107 FPRReg destFPR = FPRInfo::returnValueFPR; 1108 FPRReg selectionAFPR = FPRInfo::fpRegT1; 1109 FPRReg selectionBFPR = destFPR; 1110 FPRReg arg1FPR = FPRInfo::fpRegT3; 1111 FPRReg arg2FPR = FPRInfo::fpRegT4; 1112 1113 RELEASE_ASSERT(destFPR != selectionAFPR); 1114 RELEASE_ASSERT(destFPR == selectionBFPR); 1115 RELEASE_ASSERT(destFPR != arg1FPR); 1116 RELEASE_ASSERT(destFPR != arg2FPR); 1117 1118 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), arg1FPR); 1119 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg2), arg2FPR); 1120 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), selectionAFPR); 1121 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), selectionBFPR); 1122 jit.moveDoubleConditionallyDouble(condition, arg1FPR, arg2FPR, selectionAFPR, selectionBFPR, destFPR); 1123 1124 FPRReg tempFPR = FPRInfo::fpRegT5; 1125 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), tempFPR); 1126 auto aIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionAFPR, tempFPR); 1127 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionA), destFPR); 1128 aIsUnchanged.link(&jit); 1129 1130 emitFunctionEpilogue(jit); 1131 jit.ret(); 1132 }); 1133 1134 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, doubleOperands(), selectionA, selectionB); 1135 } 1136 1137 void testMoveDoubleConditionallyFloat(MacroAssembler::DoubleCondition condition) 1138 { 1139 float arg1 = 0; 1140 float arg2 = 0; 1141 double selectionA = 42.0; 1142 double selectionB = 17.0; 1143 double corruptedSelectionA = 55555; 1144 double corruptedSelectionB = 66666; 1145 1146 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1147 emitFunctionPrologue(jit); 1148 1149 FPRReg destFPR = FPRInfo::returnValueFPR; 1150 FPRReg selectionAFPR = FPRInfo::fpRegT1; 1151 FPRReg selectionBFPR = FPRInfo::fpRegT2; 1152 FPRReg arg1FPR = FPRInfo::fpRegT3; 1153 FPRReg arg2FPR = FPRInfo::fpRegT4; 1154 1155 RELEASE_ASSERT(destFPR != selectionAFPR); 1156 RELEASE_ASSERT(destFPR != selectionBFPR); 1157 RELEASE_ASSERT(destFPR != arg1FPR); 1158 RELEASE_ASSERT(destFPR != arg2FPR); 1159 1160 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), arg1FPR); 1161 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), arg2FPR); 1162 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), selectionAFPR); 1163 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), selectionBFPR); 1164 jit.moveDoubleConditionallyFloat(condition, arg1FPR, arg2FPR, selectionAFPR, selectionBFPR, destFPR); 1165 1166 FPRReg tempFPR = FPRInfo::fpRegT5; 1167 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), tempFPR); 1168 auto aIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionAFPR, tempFPR); 1169 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionA), destFPR); 1170 aIsUnchanged.link(&jit); 1171 1172 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), tempFPR); 1173 auto bIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionBFPR, tempFPR); 1174 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionB), destFPR); 1175 bIsUnchanged.link(&jit); 1176 1177 emitFunctionEpilogue(jit); 1178 jit.ret(); 1179 }); 1180 1181 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 1182 } 1183 1184 void testMoveDoubleConditionallyFloatDestSameAsThenCase(MacroAssembler::DoubleCondition condition) 1185 { 1186 float arg1 = 0; 1187 float arg2 = 0; 1188 double selectionA = 42.0; 1189 double selectionB = 17.0; 1190 double corruptedSelectionB = 66666; 1191 1192 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1193 emitFunctionPrologue(jit); 1194 1195 FPRReg destFPR = FPRInfo::returnValueFPR; 1196 FPRReg selectionAFPR = destFPR; 1197 FPRReg selectionBFPR = FPRInfo::fpRegT2; 1198 FPRReg arg1FPR = FPRInfo::fpRegT3; 1199 FPRReg arg2FPR = FPRInfo::fpRegT4; 1200 1201 RELEASE_ASSERT(destFPR == selectionAFPR); 1202 RELEASE_ASSERT(destFPR != selectionBFPR); 1203 RELEASE_ASSERT(destFPR != arg1FPR); 1204 RELEASE_ASSERT(destFPR != arg2FPR); 1205 1206 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), arg1FPR); 1207 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), arg2FPR); 1208 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), selectionAFPR); 1209 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), selectionBFPR); 1210 jit.moveDoubleConditionallyFloat(condition, arg1FPR, arg2FPR, selectionAFPR, selectionBFPR, destFPR); 1211 1212 FPRReg tempFPR = FPRInfo::fpRegT5; 1213 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), tempFPR); 1214 auto bIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionBFPR, tempFPR); 1215 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionB), destFPR); 1216 bIsUnchanged.link(&jit); 1217 1218 emitFunctionEpilogue(jit); 1219 jit.ret(); 1220 }); 1221 1222 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 1223 } 1224 1225 void testMoveDoubleConditionallyFloatDestSameAsElseCase(MacroAssembler::DoubleCondition condition) 1226 { 1227 float arg1 = 0; 1228 float arg2 = 0; 1229 double selectionA = 42.0; 1230 double selectionB = 17.0; 1231 double corruptedSelectionA = 55555; 1232 1233 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1234 emitFunctionPrologue(jit); 1235 1236 FPRReg destFPR = FPRInfo::returnValueFPR; 1237 FPRReg selectionAFPR = FPRInfo::fpRegT1; 1238 FPRReg selectionBFPR = destFPR; 1239 FPRReg arg1FPR = FPRInfo::fpRegT3; 1240 FPRReg arg2FPR = FPRInfo::fpRegT4; 1241 1242 RELEASE_ASSERT(destFPR != selectionAFPR); 1243 RELEASE_ASSERT(destFPR == selectionBFPR); 1244 RELEASE_ASSERT(destFPR != arg1FPR); 1245 RELEASE_ASSERT(destFPR != arg2FPR); 1246 1247 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), arg1FPR); 1248 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg2), arg2FPR); 1249 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), selectionAFPR); 1250 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), selectionBFPR); 1251 jit.moveDoubleConditionallyFloat(condition, arg1FPR, arg2FPR, selectionAFPR, selectionBFPR, destFPR); 1252 1253 FPRReg tempFPR = FPRInfo::fpRegT5; 1254 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), tempFPR); 1255 auto aIsUnchanged = jit.branchDouble(CCallHelpers::DoubleEqual, selectionAFPR, tempFPR); 1256 jit.loadDouble(CCallHelpers::TrustedImmPtr(&corruptedSelectionA), destFPR); 1257 aIsUnchanged.link(&jit); 1258 1259 emitFunctionEpilogue(jit); 1260 jit.ret(); 1261 }); 1262 1263 testMoveConditionallyFloatingPoint(condition, testCode, arg1, arg2, floatOperands(), selectionA, selectionB); 1264 } 1265 1266 template<typename T, typename SelectionType> 1267 void testMoveConditionallyFloatingPointSameArg(MacroAssembler::DoubleCondition condition, const MacroAssemblerCodeRef<JSEntryPtrTag>& testCode, T& arg1, const Vector<T> operands, SelectionType selectionA, SelectionType selectionB) 1268 { 1269 auto expectedResult = [&, condition] (T a) -> SelectionType { 1270 auto isUnordered = [] (double x) { 1271 return x != x; 1272 }; 1273 switch (condition) { 1274 case MacroAssembler::DoubleEqual: 1275 return !isUnordered(a) && (a == a) ? selectionA : selectionB; 1276 case MacroAssembler::DoubleNotEqual: 1277 return !isUnordered(a) && (a != a) ? selectionA : selectionB; 1278 case MacroAssembler::DoubleGreaterThan: 1279 return !isUnordered(a) && (a > a) ? selectionA : selectionB; 1280 case MacroAssembler::DoubleGreaterThanOrEqual: 1281 return !isUnordered(a) && (a >= a) ? selectionA : selectionB; 1282 case MacroAssembler::DoubleLessThan: 1283 return !isUnordered(a) && (a < a) ? selectionA : selectionB; 1284 case MacroAssembler::DoubleLessThanOrEqual: 1285 return !isUnordered(a) && (a <= a) ? selectionA : selectionB; 1286 case MacroAssembler::DoubleEqualOrUnordered: 1287 return isUnordered(a) || (a == a) ? selectionA : selectionB; 1288 case MacroAssembler::DoubleNotEqualOrUnordered: 1289 return isUnordered(a) || (a != a) ? selectionA : selectionB; 1290 case MacroAssembler::DoubleGreaterThanOrUnordered: 1291 return isUnordered(a) || (a > a) ? selectionA : selectionB; 1292 case MacroAssembler::DoubleGreaterThanOrEqualOrUnordered: 1293 return isUnordered(a) || (a >= a) ? selectionA : selectionB; 1294 case MacroAssembler::DoubleLessThanOrUnordered: 1295 return isUnordered(a) || (a < a) ? selectionA : selectionB; 1296 case MacroAssembler::DoubleLessThanOrEqualOrUnordered: 1297 return isUnordered(a) || (a <= a) ? selectionA : selectionB; 1298 } // switch 1299 }; 1300 1301 for (auto a : operands) { 1302 arg1 = a; 1303 CHECK_EQ(invoke<SelectionType>(testCode), expectedResult(a)); 1304 } 1305 } 1306 1307 void testMoveConditionallyDouble2SameArg(MacroAssembler::DoubleCondition condition) 1308 { 1309 double arg1 = 0; 1310 unsigned selectionA = 42; 1311 unsigned selectionB = 17; 1312 1313 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1314 emitFunctionPrologue(jit); 1315 1316 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 1317 RELEASE_ASSERT(GPRInfo::returnValueGPR != selectionAGPR); 1318 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 1319 jit.move(CCallHelpers::TrustedImm32(selectionB), GPRInfo::returnValueGPR); 1320 1321 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 1322 jit.moveConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, selectionAGPR, GPRInfo::returnValueGPR); 1323 1324 emitFunctionEpilogue(jit); 1325 jit.ret(); 1326 }); 1327 1328 testMoveConditionallyFloatingPointSameArg(condition, testCode, arg1, doubleOperands(), selectionA, selectionB); 1329 } 1330 1331 void testMoveConditionallyDouble3SameArg(MacroAssembler::DoubleCondition condition) 1332 { 1333 double arg1 = 0; 1334 unsigned selectionA = 42; 1335 unsigned selectionB = 17; 1336 1337 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1338 emitFunctionPrologue(jit); 1339 1340 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 1341 GPRReg selectionBGPR = GPRInfo::argumentGPR3; 1342 RELEASE_ASSERT(GPRInfo::returnValueGPR != selectionAGPR); 1343 RELEASE_ASSERT(GPRInfo::returnValueGPR != selectionBGPR); 1344 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 1345 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 1346 jit.move(CCallHelpers::TrustedImm32(-1), GPRInfo::returnValueGPR); 1347 1348 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 1349 jit.moveConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, selectionAGPR, selectionBGPR, GPRInfo::returnValueGPR); 1350 1351 emitFunctionEpilogue(jit); 1352 jit.ret(); 1353 }); 1354 1355 testMoveConditionallyFloatingPointSameArg(condition, testCode, arg1, doubleOperands(), selectionA, selectionB); 1356 } 1357 1358 void testMoveConditionallyFloat2SameArg(MacroAssembler::DoubleCondition condition) 1359 { 1360 float arg1 = 0; 1361 unsigned selectionA = 42; 1362 unsigned selectionB = 17; 1363 1364 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1365 emitFunctionPrologue(jit); 1366 1367 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 1368 RELEASE_ASSERT(GPRInfo::returnValueGPR != selectionAGPR); 1369 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 1370 jit.move(CCallHelpers::TrustedImm32(selectionB), GPRInfo::returnValueGPR); 1371 1372 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 1373 jit.moveConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, selectionAGPR, GPRInfo::returnValueGPR); 1374 1375 emitFunctionEpilogue(jit); 1376 jit.ret(); 1377 }); 1378 1379 testMoveConditionallyFloatingPointSameArg(condition, testCode, arg1, floatOperands(), selectionA, selectionB); 1380 } 1381 1382 void testMoveConditionallyFloat3SameArg(MacroAssembler::DoubleCondition condition) 1383 { 1384 float arg1 = 0; 1385 unsigned selectionA = 42; 1386 unsigned selectionB = 17; 1387 1388 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1389 emitFunctionPrologue(jit); 1390 1391 GPRReg selectionAGPR = GPRInfo::argumentGPR2; 1392 GPRReg selectionBGPR = GPRInfo::argumentGPR3; 1393 RELEASE_ASSERT(GPRInfo::returnValueGPR != selectionAGPR); 1394 RELEASE_ASSERT(GPRInfo::returnValueGPR != selectionBGPR); 1395 jit.move(CCallHelpers::TrustedImm32(selectionA), selectionAGPR); 1396 jit.move(CCallHelpers::TrustedImm32(selectionB), selectionBGPR); 1397 jit.move(CCallHelpers::TrustedImm32(-1), GPRInfo::returnValueGPR); 1398 1399 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 1400 jit.moveConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, selectionAGPR, selectionBGPR, GPRInfo::returnValueGPR); 1401 1402 emitFunctionEpilogue(jit); 1403 jit.ret(); 1404 }); 1405 1406 testMoveConditionallyFloatingPointSameArg(condition, testCode, arg1, floatOperands(), selectionA, selectionB); 1407 } 1408 1409 void testMoveDoubleConditionallyDoubleSameArg(MacroAssembler::DoubleCondition condition) 1410 { 1411 double arg1 = 0; 1412 double selectionA = 42.0; 1413 double selectionB = 17.0; 1414 1415 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1416 emitFunctionPrologue(jit); 1417 1418 jit.loadDouble(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 1419 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), FPRInfo::fpRegT2); 1420 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), FPRInfo::fpRegT3); 1421 jit.moveDoubleConditionallyDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, FPRInfo::fpRegT2, FPRInfo::fpRegT3, FPRInfo::returnValueFPR); 1422 1423 emitFunctionEpilogue(jit); 1424 jit.ret(); 1425 }); 1426 1427 testMoveConditionallyFloatingPointSameArg(condition, testCode, arg1, doubleOperands(), selectionA, selectionB); 1428 } 1429 1430 void testMoveDoubleConditionallyFloatSameArg(MacroAssembler::DoubleCondition condition) 1431 { 1432 float arg1 = 0; 1433 double selectionA = 42.0; 1434 double selectionB = 17.0; 1435 1436 auto testCode = compile([&, condition] (CCallHelpers& jit) { 1437 emitFunctionPrologue(jit); 1438 1439 jit.loadFloat(CCallHelpers::TrustedImmPtr(&arg1), FPRInfo::fpRegT0); 1440 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionA), FPRInfo::fpRegT2); 1441 jit.loadDouble(CCallHelpers::TrustedImmPtr(&selectionB), FPRInfo::fpRegT3); 1442 jit.moveDoubleConditionallyFloat(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT0, FPRInfo::fpRegT2, FPRInfo::fpRegT3, FPRInfo::returnValueFPR); 1443 1444 emitFunctionEpilogue(jit); 1445 jit.ret(); 1446 }); 1447 1448 testMoveConditionallyFloatingPointSameArg(condition, testCode, arg1, floatOperands(), selectionA, selectionB); 1449 } 1450 1451 #endif // CPU(X86_64) || CPU(ARM64) 590 1452 591 1453 #if ENABLE(MASM_PROBE) … … 1338 2200 RUN(testBranchTruncateDoubleToInt32(123, 123)); 1339 2201 1340 RUN(testCompareDouble(MacroAssembler::DoubleEqual)); 1341 RUN(testCompareDouble(MacroAssembler::DoubleNotEqual)); 1342 RUN(testCompareDouble(MacroAssembler::DoubleGreaterThan)); 1343 RUN(testCompareDouble(MacroAssembler::DoubleGreaterThanOrEqual)); 1344 RUN(testCompareDouble(MacroAssembler::DoubleLessThan)); 1345 RUN(testCompareDouble(MacroAssembler::DoubleLessThanOrEqual)); 1346 RUN(testCompareDouble(MacroAssembler::DoubleEqualOrUnordered)); 1347 RUN(testCompareDouble(MacroAssembler::DoubleNotEqualOrUnordered)); 1348 RUN(testCompareDouble(MacroAssembler::DoubleGreaterThanOrUnordered)); 1349 RUN(testCompareDouble(MacroAssembler::DoubleGreaterThanOrEqualOrUnordered)); 1350 RUN(testCompareDouble(MacroAssembler::DoubleLessThanOrUnordered)); 1351 RUN(testCompareDouble(MacroAssembler::DoubleLessThanOrEqualOrUnordered)); 2202 #define FOR_EACH_DOUBLE_CONDITION_RUN(__test) \ 2203 do { \ 2204 RUN(__test(MacroAssembler::DoubleEqual)); \ 2205 RUN(__test(MacroAssembler::DoubleNotEqual)); \ 2206 RUN(__test(MacroAssembler::DoubleGreaterThan)); \ 2207 RUN(__test(MacroAssembler::DoubleGreaterThanOrEqual)); \ 2208 RUN(__test(MacroAssembler::DoubleLessThan)); \ 2209 RUN(__test(MacroAssembler::DoubleLessThanOrEqual)); \ 2210 RUN(__test(MacroAssembler::DoubleEqualOrUnordered)); \ 2211 RUN(__test(MacroAssembler::DoubleNotEqualOrUnordered)); \ 2212 RUN(__test(MacroAssembler::DoubleGreaterThanOrUnordered)); \ 2213 RUN(__test(MacroAssembler::DoubleGreaterThanOrEqualOrUnordered)); \ 2214 RUN(__test(MacroAssembler::DoubleLessThanOrUnordered)); \ 2215 RUN(__test(MacroAssembler::DoubleLessThanOrEqualOrUnordered)); \ 2216 } while (false) 2217 2218 FOR_EACH_DOUBLE_CONDITION_RUN(testCompareDouble); 2219 FOR_EACH_DOUBLE_CONDITION_RUN(testCompareDoubleSameArg); 2220 1352 2221 RUN(testMul32WithImmediates()); 1353 2222 … … 1366 2235 1367 2236 #if CPU(X86) || CPU(X86_64) || CPU(ARM64) 1368 RUN(testCompareFloat(MacroAssembler::DoubleEqual)); 1369 RUN(testCompareFloat(MacroAssembler::DoubleNotEqual)); 1370 RUN(testCompareFloat(MacroAssembler::DoubleGreaterThan)); 1371 RUN(testCompareFloat(MacroAssembler::DoubleGreaterThanOrEqual)); 1372 RUN(testCompareFloat(MacroAssembler::DoubleLessThan)); 1373 RUN(testCompareFloat(MacroAssembler::DoubleLessThanOrEqual)); 1374 RUN(testCompareFloat(MacroAssembler::DoubleEqualOrUnordered)); 1375 RUN(testCompareFloat(MacroAssembler::DoubleNotEqualOrUnordered)); 1376 RUN(testCompareFloat(MacroAssembler::DoubleGreaterThanOrUnordered)); 1377 RUN(testCompareFloat(MacroAssembler::DoubleGreaterThanOrEqualOrUnordered)); 1378 RUN(testCompareFloat(MacroAssembler::DoubleLessThanOrUnordered)); 1379 RUN(testCompareFloat(MacroAssembler::DoubleLessThanOrEqualOrUnordered)); 2237 FOR_EACH_DOUBLE_CONDITION_RUN(testCompareFloat); 2238 #endif 2239 2240 #if CPU(X86_64) || CPU(ARM64) 2241 // Comparing 2 different registers. 2242 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyDouble2); 2243 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyDouble3); 2244 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyDouble3DestSameAsThenCase); 2245 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyDouble3DestSameAsElseCase); 2246 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyFloat2); 2247 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyFloat3); 2248 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyFloat3DestSameAsThenCase); 2249 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyFloat3DestSameAsElseCase); 2250 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyDouble); 2251 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyDoubleDestSameAsThenCase); 2252 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyDoubleDestSameAsElseCase); 2253 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyFloat); 2254 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyFloatDestSameAsThenCase); 2255 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyFloatDestSameAsElseCase); 2256 2257 // Comparing the same register against itself. 2258 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyDouble2SameArg); 2259 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyDouble3SameArg); 2260 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyFloat2SameArg); 2261 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveConditionallyFloat3SameArg); 2262 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyDoubleSameArg); 2263 FOR_EACH_DOUBLE_CONDITION_RUN(testMoveDoubleConditionallyFloatSameArg); 1380 2264 #endif 1381 2265
Note:
See TracChangeset
for help on using the changeset viewer.