3806 |
3806 |
3807 // That's it |
3807 // That's it |
3808 masm.bind(DONE_LABEL); |
3808 masm.bind(DONE_LABEL); |
3809 %} |
3809 %} |
3810 |
3810 |
|
3811 enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{ |
|
3812 Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP; |
|
3813 MacroAssembler masm(&cbuf); |
|
3814 |
|
3815 Register ary1Reg = as_Register($ary1$$reg); |
|
3816 Register ary2Reg = as_Register($ary2$$reg); |
|
3817 Register tmp1Reg = as_Register($tmp1$$reg); |
|
3818 Register tmp2Reg = as_Register($tmp2$$reg); |
|
3819 Register resultReg = as_Register($result$$reg); |
|
3820 |
|
3821 int length_offset = arrayOopDesc::length_offset_in_bytes(); |
|
3822 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); |
|
3823 |
|
3824 // Check the input args |
|
3825 masm.cmpq(ary1Reg, ary2Reg); |
|
3826 masm.jcc(Assembler::equal, TRUE_LABEL); |
|
3827 masm.testq(ary1Reg, ary1Reg); |
|
3828 masm.jcc(Assembler::zero, FALSE_LABEL); |
|
3829 masm.testq(ary2Reg, ary2Reg); |
|
3830 masm.jcc(Assembler::zero, FALSE_LABEL); |
|
3831 |
|
3832 // Check the lengths |
|
3833 masm.movl(tmp2Reg, Address(ary1Reg, length_offset)); |
|
3834 masm.movl(resultReg, Address(ary2Reg, length_offset)); |
|
3835 masm.cmpl(tmp2Reg, resultReg); |
|
3836 masm.jcc(Assembler::notEqual, FALSE_LABEL); |
|
3837 masm.testl(resultReg, resultReg); |
|
3838 masm.jcc(Assembler::zero, TRUE_LABEL); |
|
3839 |
|
3840 // Get the number of 4 byte vectors to compare |
|
3841 masm.shrl(resultReg, 1); |
|
3842 |
|
3843 // Check for odd-length arrays |
|
3844 masm.andl(tmp2Reg, 1); |
|
3845 masm.testl(tmp2Reg, tmp2Reg); |
|
3846 masm.jcc(Assembler::zero, COMPARE_LOOP_HDR); |
|
3847 |
|
3848 // Compare 2-byte "tail" at end of arrays |
|
3849 masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); |
|
3850 masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); |
|
3851 masm.cmpl(tmp1Reg, tmp2Reg); |
|
3852 masm.jcc(Assembler::notEqual, FALSE_LABEL); |
|
3853 masm.testl(resultReg, resultReg); |
|
3854 masm.jcc(Assembler::zero, TRUE_LABEL); |
|
3855 |
|
3856 // Setup compare loop |
|
3857 masm.bind(COMPARE_LOOP_HDR); |
|
3858 // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays |
|
3859 masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); |
|
3860 masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); |
|
3861 masm.negq(resultReg); |
|
3862 |
|
3863 // 4-byte-wide compare loop |
|
3864 masm.bind(COMPARE_LOOP); |
|
3865 masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0)); |
|
3866 masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0)); |
|
3867 masm.cmpl(ary1Reg, ary2Reg); |
|
3868 masm.jcc(Assembler::notEqual, FALSE_LABEL); |
|
3869 masm.incrementq(resultReg); |
|
3870 masm.jcc(Assembler::notZero, COMPARE_LOOP); |
|
3871 |
|
3872 masm.bind(TRUE_LABEL); |
|
3873 masm.movl(resultReg, 1); // return true |
|
3874 masm.jmp(DONE_LABEL); |
|
3875 |
|
3876 masm.bind(FALSE_LABEL); |
|
3877 masm.xorl(resultReg, resultReg); // return false |
|
3878 |
|
3879 // That's it |
|
3880 masm.bind(DONE_LABEL); |
|
3881 %} |
|
3882 |
3811 enc_class enc_rethrow() |
3883 enc_class enc_rethrow() |
3812 %{ |
3884 %{ |
3813 cbuf.set_inst_mark(); |
3885 cbuf.set_inst_mark(); |
3814 emit_opcode(cbuf, 0xE9); // jmp entry |
3886 emit_opcode(cbuf, 0xE9); // jmp entry |
3815 emit_d32_reloc(cbuf, |
3887 emit_d32_reloc(cbuf, |
10871 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr); |
10943 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr); |
10872 //ins_cost(300); |
10944 //ins_cost(300); |
10873 |
10945 |
10874 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} |
10946 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} |
10875 ins_encode( enc_String_Compare() ); |
10947 ins_encode( enc_String_Compare() ); |
|
10948 ins_pipe( pipe_slow ); |
|
10949 %} |
|
10950 |
|
10951 // fast array equals |
|
10952 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, |
|
10953 rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{ |
|
10954 match(Set result (AryEq ary1 ary2)); |
|
10955 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr); |
|
10956 //ins_cost(300); |
|
10957 |
|
10958 format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %} |
|
10959 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) ); |
10876 ins_pipe( pipe_slow ); |
10960 ins_pipe( pipe_slow ); |
10877 %} |
10961 %} |
10878 |
10962 |
10879 //----------Control Flow Instructions------------------------------------------ |
10963 //----------Control Flow Instructions------------------------------------------ |
10880 // Signed compare Instructions |
10964 // Signed compare Instructions |