src/cpu/x86/vm/x86_64.ad

changeset 604
9148c65abefc
parent 603
7793bd37a336
child 617
44abbb0d4c18
     1.1 --- a/src/cpu/x86/vm/x86_64.ad	Thu May 29 12:04:14 2008 -0700
     1.2 +++ b/src/cpu/x86/vm/x86_64.ad	Thu May 29 16:22:09 2008 -0700
     1.3 @@ -3808,6 +3808,78 @@
     1.4      masm.bind(DONE_LABEL);
     1.5    %}
     1.6  
     1.7 +  enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{
     1.8 +    Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
     1.9 +    MacroAssembler masm(&cbuf);
    1.10 +
    1.11 +    Register ary1Reg   = as_Register($ary1$$reg);
    1.12 +    Register ary2Reg   = as_Register($ary2$$reg);
    1.13 +    Register tmp1Reg   = as_Register($tmp1$$reg);
    1.14 +    Register tmp2Reg   = as_Register($tmp2$$reg);
    1.15 +    Register resultReg = as_Register($result$$reg);
    1.16 +
    1.17 +    int length_offset  = arrayOopDesc::length_offset_in_bytes();
    1.18 +    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
    1.19 +
    1.20 +    // Check the input args
    1.21 +    masm.cmpq(ary1Reg, ary2Reg);                        
    1.22 +    masm.jcc(Assembler::equal, TRUE_LABEL);
    1.23 +    masm.testq(ary1Reg, ary1Reg);                       
    1.24 +    masm.jcc(Assembler::zero, FALSE_LABEL);
    1.25 +    masm.testq(ary2Reg, ary2Reg);                       
    1.26 +    masm.jcc(Assembler::zero, FALSE_LABEL);
    1.27 +
    1.28 +    // Check the lengths
    1.29 +    masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
    1.30 +    masm.movl(resultReg, Address(ary2Reg, length_offset));
    1.31 +    masm.cmpl(tmp2Reg, resultReg);
    1.32 +    masm.jcc(Assembler::notEqual, FALSE_LABEL);
    1.33 +    masm.testl(resultReg, resultReg);
    1.34 +    masm.jcc(Assembler::zero, TRUE_LABEL);
    1.35 +
    1.36 +    // Get the number of 4 byte vectors to compare
    1.37 +    masm.shrl(resultReg, 1);
    1.38 +
    1.39 +    // Check for odd-length arrays
    1.40 +    masm.andl(tmp2Reg, 1);
    1.41 +    masm.testl(tmp2Reg, tmp2Reg);
    1.42 +    masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
    1.43 +
    1.44 +    // Compare 2-byte "tail" at end of arrays
    1.45 +    masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
    1.46 +    masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
    1.47 +    masm.cmpl(tmp1Reg, tmp2Reg);
    1.48 +    masm.jcc(Assembler::notEqual, FALSE_LABEL);
    1.49 +    masm.testl(resultReg, resultReg);
    1.50 +    masm.jcc(Assembler::zero, TRUE_LABEL);
    1.51 +
    1.52 +    // Setup compare loop
    1.53 +    masm.bind(COMPARE_LOOP_HDR);
    1.54 +    // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
    1.55 +    masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
    1.56 +    masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
    1.57 +    masm.negq(resultReg);
    1.58 +
    1.59 +    // 4-byte-wide compare loop
    1.60 +    masm.bind(COMPARE_LOOP);
    1.61 +    masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
    1.62 +    masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
    1.63 +    masm.cmpl(ary1Reg, ary2Reg);
    1.64 +    masm.jcc(Assembler::notEqual, FALSE_LABEL);
    1.65 +    masm.incrementq(resultReg);
    1.66 +    masm.jcc(Assembler::notZero, COMPARE_LOOP);
    1.67 +
    1.68 +    masm.bind(TRUE_LABEL);
    1.69 +    masm.movl(resultReg, 1);   // return true
    1.70 +    masm.jmp(DONE_LABEL);
    1.71 +
    1.72 +    masm.bind(FALSE_LABEL);
    1.73 +    masm.xorl(resultReg, resultReg); // return false
    1.74 +
    1.75 +    // That's it
    1.76 +    masm.bind(DONE_LABEL);
    1.77 +  %}
    1.78 +
    1.79    enc_class enc_rethrow()
    1.80    %{
    1.81      cbuf.set_inst_mark();
    1.82 @@ -10876,6 +10948,18 @@
    1.83    ins_pipe( pipe_slow );
    1.84  %}
    1.85  
    1.86 +// fast array equals
    1.87 +instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, 
    1.88 +                      rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{
    1.89 +  match(Set result (AryEq ary1 ary2));
    1.90 +  effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
    1.91 +  //ins_cost(300);
    1.92 +
    1.93 +  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL RAX, RBX" %}
    1.94 +  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
    1.95 +  ins_pipe( pipe_slow );
    1.96 +%}
    1.97 +
    1.98  //----------Control Flow Instructions------------------------------------------
    1.99  // Signed compare Instructions
   1.100  

mercurial