Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_32.ad @ 344:6aae2f9d0294
Merge
author | ysr |
---|---|
date | Thu, 12 Jun 2008 13:50:55 -0700 |
parents | 9148c65abefc |
children | d1605aabd0a1 ab65a4c9b2e8 |
comparison
equal
deleted
inserted
replaced
342:37f87013dfd8 | 344:6aae2f9d0294 |
---|---|
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 |