src/cpu/x86/vm/x86_64.ad

changeset 604
9148c65abefc
parent 603
7793bd37a336
child 617
44abbb0d4c18
equal deleted inserted replaced
603:7793bd37a336 604:9148c65abefc
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

mercurial