comparison src/cpu/x86/vm/x86_32.ad @ 169:9148c65abefc

6695049: (coll) Create an x86 intrinsic for Arrays.equals Summary: Intrinsify java/util/Arrays.equals(char[], char[]) Reviewed-by: kvn, never
author rasbold
date Thu, 29 May 2008 16:22:09 -0700
parents ba764ed4b6f2
children d1605aabd0a1 ab65a4c9b2e8
comparison
equal deleted inserted replaced
168:7793bd37a336 169:9148c65abefc
3804 3804
3805 // That's it 3805 // That's it
3806 masm.bind(DONE_LABEL); 3806 masm.bind(DONE_LABEL);
3807 %} 3807 %}
3808 3808
3809 enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result) %{
3810 Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
3811 MacroAssembler masm(&cbuf);
3812
3813 Register ary1Reg = as_Register($ary1$$reg);
3814 Register ary2Reg = as_Register($ary2$$reg);
3815 Register tmp1Reg = as_Register($tmp1$$reg);
3816 Register tmp2Reg = as_Register($tmp2$$reg);
3817 Register resultReg = as_Register($result$$reg);
3818
3819 int length_offset = arrayOopDesc::length_offset_in_bytes();
3820 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3821
3822 // Check the input args
3823 masm.cmpl(ary1Reg, ary2Reg);
3824 masm.jcc(Assembler::equal, TRUE_LABEL);
3825 masm.testl(ary1Reg, ary1Reg);
3826 masm.jcc(Assembler::zero, FALSE_LABEL);
3827 masm.testl(ary2Reg, ary2Reg);
3828 masm.jcc(Assembler::zero, FALSE_LABEL);
3829
3830 // Check the lengths
3831 masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
3832 masm.movl(resultReg, Address(ary2Reg, length_offset));
3833 masm.cmpl(tmp2Reg, resultReg);
3834 masm.jcc(Assembler::notEqual, FALSE_LABEL);
3835 masm.testl(resultReg, resultReg);
3836 masm.jcc(Assembler::zero, TRUE_LABEL);
3837
3838 // Get the number of 4 byte vectors to compare
3839 masm.shrl(resultReg, 1);
3840
3841 // Check for odd-length arrays
3842 masm.andl(tmp2Reg, 1);
3843 masm.testl(tmp2Reg, tmp2Reg);
3844 masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
3845
3846 // Compare 2-byte "tail" at end of arrays
3847 masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
3848 masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
3849 masm.cmpl(tmp1Reg, tmp2Reg);
3850 masm.jcc(Assembler::notEqual, FALSE_LABEL);
3851 masm.testl(resultReg, resultReg);
3852 masm.jcc(Assembler::zero, TRUE_LABEL);
3853
3854 // Setup compare loop
3855 masm.bind(COMPARE_LOOP_HDR);
3856 // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
3857 masm.leal(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
3858 masm.leal(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
3859 masm.negl(resultReg);
3860
3861 // 4-byte-wide compare loop
3862 masm.bind(COMPARE_LOOP);
3863 masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
3864 masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
3865 masm.cmpl(ary1Reg, ary2Reg);
3866 masm.jcc(Assembler::notEqual, FALSE_LABEL);
3867 masm.increment(resultReg);
3868 masm.jcc(Assembler::notZero, COMPARE_LOOP);
3869
3870 masm.bind(TRUE_LABEL);
3871 masm.movl(resultReg, 1); // return true
3872 masm.jmp(DONE_LABEL);
3873
3874 masm.bind(FALSE_LABEL);
3875 masm.xorl(resultReg, resultReg); // return false
3876
3877 // That's it
3878 masm.bind(DONE_LABEL);
3879 %}
3880
3809 enc_class enc_pop_rdx() %{ 3881 enc_class enc_pop_rdx() %{
3810 emit_opcode(cbuf,0x5A); 3882 emit_opcode(cbuf,0x5A);
3811 %} 3883 %}
3812 3884
3813 enc_class enc_rethrow() %{ 3885 enc_class enc_rethrow() %{
11560 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr); 11632 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr);
11561 //ins_cost(300); 11633 //ins_cost(300);
11562 11634
11563 format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %} 11635 format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %}
11564 ins_encode( enc_String_Compare() ); 11636 ins_encode( enc_String_Compare() );
11637 ins_pipe( pipe_slow );
11638 %}
11639
11640 // fast array equals
11641 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{
11642 match(Set result (AryEq ary1 ary2));
11643 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
11644 //ins_cost(300);
11645
11646 format %{ "Array Equals $ary1,$ary2 -> $result // KILL EAX, EBX" %}
11647 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
11565 ins_pipe( pipe_slow ); 11648 ins_pipe( pipe_slow );
11566 %} 11649 %}
11567 11650
11568 //----------Control Flow Instructions------------------------------------------ 11651 //----------Control Flow Instructions------------------------------------------
11569 // Signed compare Instructions 11652 // Signed compare Instructions