--- old/src/cpu/x86/vm/x86_64.ad Tue Aug 18 19:06:17 2009 +++ new/src/cpu/x86/vm/x86_64.ad Tue Aug 18 19:06:17 2009 @@ -3701,8 +3701,8 @@ } %} - enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, - rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{ + enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, rbx_RegI cnt1, rax_RegI cnt2, + regD tmp1, regD tmp2, rcx_RegI result) %{ Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, CONT_LABEL, WHILE_HEAD_LABEL; @@ -3711,44 +3711,28 @@ XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg); - // Get the first character position in both strings - // [8] char array, [12] offset, [16] count - int value_offset = java_lang_String::value_offset_in_bytes(); - int offset_offset = java_lang_String::offset_offset_in_bytes(); - int count_offset = java_lang_String::count_offset_in_bytes(); - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); - - masm.load_heap_oop(rax, Address(rsi, value_offset)); - masm.movl(rcx, Address(rsi, offset_offset)); - masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); - masm.load_heap_oop(rbx, Address(rdi, value_offset)); - masm.movl(rcx, Address(rdi, offset_offset)); - masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); - // Compute the minimum of the string lengths(rsi) and the // difference of the string lengths (stack) // do the conditional move stuff - masm.movl(rdi, Address(rdi, count_offset)); - masm.movl(rsi, Address(rsi, count_offset)); - masm.movl(rcx, rdi); - masm.subl(rdi, rsi); - masm.push(rdi); - masm.cmov(Assembler::lessEqual, rsi, rcx); + masm.movl(rcx, rbx); + masm.subl(rbx, rax); + masm.push(rbx); + masm.cmov(Assembler::lessEqual, rax, rcx); // Is the minimum length zero? masm.bind(RCX_GOOD_LABEL); - masm.testl(rsi, rsi); + masm.testl(rax, rax); masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); // Load first characters - masm.load_unsigned_short(rcx, Address(rbx, 0)); - masm.load_unsigned_short(rdi, Address(rax, 0)); + masm.load_unsigned_short(rcx, Address(rdi, 0)); + masm.load_unsigned_short(rbx, Address(rsi, 0)); // Compare first characters - masm.subl(rcx, rdi); + masm.subl(rcx, rbx); masm.jcc(Assembler::notZero, POP_LABEL); - masm.decrementl(rsi); + masm.decrementl(rax); masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); { @@ -3755,7 +3739,7 @@ // Check after comparing first character to see if strings are equivalent Label LSkip2; // Check if the strings start at same location - masm.cmpptr(rbx, rax); + masm.cmpptr(rdi, rsi); masm.jccb(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) @@ -3767,60 +3751,60 @@ } // Advance to next character - masm.addptr(rax, 2); - masm.addptr(rbx, 2); + masm.addptr(rsi, 2); + masm.addptr(rdi, 2); if (UseSSE42Intrinsics) { // With SSE4.2, use double quad vector compare Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL; // Setup to compare 16-byte vectors - masm.movl(rdi, rsi); - masm.andl(rsi, 0xfffffff8); // rsi holds the vector count - masm.andl(rdi, 0x00000007); // rdi holds the tail count - masm.testl(rsi, rsi); + masm.movl(rbx, rax); + masm.andl(rax, 0xfffffff8); // rax holds the vector count + masm.andl(rbx, 0x00000007); // rbx holds the tail count + masm.testl(rax, rax); masm.jccb(Assembler::zero, COMPARE_TAIL); - masm.lea(rax, Address(rax, rsi, Address::times_2)); - masm.lea(rbx, Address(rbx, rsi, Address::times_2)); - masm.negptr(rsi); + masm.lea(rsi, Address(rsi, rax, Address::times_2)); + masm.lea(rdi, Address(rdi, rax, Address::times_2)); + masm.negptr(rax); masm.bind(COMPARE_VECTORS); - masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2)); - masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2)); + masm.movdqu(tmp1Reg, Address(rsi, rax, Address::times_2)); + masm.movdqu(tmp2Reg, Address(rdi, rax, Address::times_2)); masm.pxor(tmp1Reg, tmp2Reg); masm.ptest(tmp1Reg, tmp1Reg); masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL); - masm.addptr(rsi, 8); + masm.addptr(rax, 8); masm.jcc(Assembler::notZero, COMPARE_VECTORS); masm.jmpb(COMPARE_TAIL); // Mismatched characters in the vectors masm.bind(VECTOR_NOT_EQUAL); - masm.lea(rax, Address(rax, rsi, Address::times_2)); - masm.lea(rbx, Address(rbx, rsi, Address::times_2)); - masm.movl(rdi, 8); + masm.lea(rsi, Address(rsi, rax, Address::times_2)); + masm.lea(rdi, Address(rdi, rax, Address::times_2)); + masm.movl(rbx, 8); // Compare tail (< 8 chars), or rescan last vectors to // find 1st mismatched characters masm.bind(COMPARE_TAIL); - masm.testl(rdi, rdi); + masm.testl(rbx, rbx); masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL); - masm.movl(rsi, rdi); + masm.movl(rax, rbx); // Fallthru to tail compare } - // Shift RAX and RBX to the end of the arrays, negate min - masm.lea(rax, Address(rax, rsi, Address::times_2, 0)); - masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0)); - masm.negptr(rsi); + // Shift rsi and rdi to the end of the arrays, negate min + masm.lea(rsi, Address(rsi, rax, Address::times_2, 0)); + masm.lea(rdi, Address(rdi, rax, Address::times_2, 0)); + masm.negptr(rax); // Compare the rest of the characters masm.bind(WHILE_HEAD_LABEL); - masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0)); - masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0)); - masm.subl(rcx, rdi); + masm.load_unsigned_short(rcx, Address(rdi, rax, Address::times_2, 0)); + masm.load_unsigned_short(rbx, Address(rsi, rax, Address::times_2, 0)); + masm.subl(rcx, rbx); masm.jccb(Assembler::notZero, POP_LABEL); - masm.increment(rsi); + masm.increment(rax); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. @@ -3836,8 +3820,8 @@ masm.bind(DONE_LABEL); %} - enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2, - rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{ + enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, rdx_RegI cnt1, rax_RegI cnt2, + regD tmp1, rcx_RegI tmp2, rbx_RegI result) %{ // SSE4.2 version Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR, SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE; @@ -3845,31 +3829,11 @@ XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); - // Get the first character position in both strings - // [8] char array, [12] offset, [16] count - int value_offset = java_lang_String::value_offset_in_bytes(); - int offset_offset = java_lang_String::offset_offset_in_bytes(); - int count_offset = java_lang_String::count_offset_in_bytes(); - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); - - // Get counts for string and substr - masm.movl(rdx, Address(rsi, count_offset)); - masm.movl(rax, Address(rdi, count_offset)); - // Check for substr count > string count - masm.cmpl(rax, rdx); - masm.jcc(Assembler::greater, RET_NEG_ONE); - // Start the indexOf operation // Get start addr of string - masm.load_heap_oop(rbx, Address(rsi, value_offset)); - masm.movl(rcx, Address(rsi, offset_offset)); - masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset)); masm.push(rsi); // Get start addr of substr - masm.load_heap_oop(rbx, Address(rdi, value_offset)); - masm.movl(rcx, Address(rdi, offset_offset)); - masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset)); masm.push(rdi); masm.push(rax); masm.jmpb(PREP_FOR_SCAN); @@ -3893,6 +3857,14 @@ masm.bind(SCAN_TO_SUBSTR); masm.subq(rdx, 8); masm.addptr(rsi, 16); + // pcmpestri + // inputs: + // xmm - substring + // rax - substring length (elements count) + // mem - scaned string + // rdx - string length (elements count) + // outputs: + // rcx - matched index in string masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d); masm.jcc(Assembler::above, SCAN_TO_SUBSTR); masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); @@ -3899,7 +3871,7 @@ // Fallthru: found a potential substr - //Make sure string is still long enough + // Make sure string is still long enough masm.subl(rdx, rcx); masm.cmpl(rdx, rax); masm.jccb(Assembler::negative, RET_NOT_FOUND); @@ -3943,8 +3915,8 @@ masm.bind(DONE); %} - enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, - rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{ + enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, regD tmp1, + regD tmp2, rbx_RegI tmp3, rax_RegI result) %{ Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR; MacroAssembler masm(&cbuf); @@ -3951,33 +3923,14 @@ XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg); - int value_offset = java_lang_String::value_offset_in_bytes(); - int offset_offset = java_lang_String::offset_offset_in_bytes(); - int count_offset = java_lang_String::count_offset_in_bytes(); - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); - - // does source == target string? + // does source == target? masm.cmpptr(rdi, rsi); masm.jcc(Assembler::equal, RET_TRUE); - // get and compare counts - masm.movl(rcx, Address(rdi, count_offset)); - masm.movl(rax, Address(rsi, count_offset)); - masm.cmpl(rcx, rax); - masm.jcc(Assembler::notEqual, RET_FALSE); - masm.testl(rax, rax); + // count == 0 + masm.testl(rcx, rcx); masm.jcc(Assembler::zero, RET_TRUE); - // get source string offset and value - masm.load_heap_oop(rbx, Address(rsi, value_offset)); - masm.movl(rax, Address(rsi, offset_offset)); - masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset)); - - // get compare string offset and value - masm.load_heap_oop(rbx, Address(rdi, value_offset)); - masm.movl(rax, Address(rdi, offset_offset)); - masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset)); - // Set byte count masm.shll(rcx, 1); masm.movl(rax, rcx); @@ -12096,39 +12049,39 @@ ins_pipe(pipe_slow); %} -instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, - rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr) +instruct string_compare(rdi_RegP str1, rsi_RegP str2, rbx_RegI cnt1, rax_RegI cnt2, + regD tmp1, regD tmp2, rcx_RegI result, rFlagsReg cr) %{ - match(Set result (StrComp str1 str2)); - effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); + match(Set result (StrComp (Binary str1 str2) (Binary cnt1 cnt2))); + effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); //ins_cost(300); - format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} - ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); + format %{ "String Compare $str1,$str2,$cnt1,$cnt2 -> $result // KILL $tmp1, $tmp2" %} + ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, tmp1, tmp2, result) ); ins_pipe( pipe_slow ); %} -instruct string_indexof(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2, - rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr) +instruct string_indexof(rsi_RegP str1, rdi_RegP str2, rdx_RegI cnt1, rax_RegI cnt2, + regD tmp1, rcx_RegI tmp2, rbx_RegI result, rFlagsReg cr) %{ predicate(UseSSE42Intrinsics); - match(Set result (StrIndexOf str1 str2)); - effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); + match(Set result (StrIndexOf (Binary str1 str2) (Binary cnt1 cnt2))); + effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr); - format %{ "String IndexOf $str1,$str2 -> $result // KILL RAX, RCX, RDX" %} - ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); + format %{ "String IndexOf $str1,$str2,$cnt1,$cnt2 -> $result // KILL $tmp1, $tmp2" %} + ins_encode( enc_String_IndexOf(str1, str2, cnt1, cnt2, tmp1, tmp2, result) ); ins_pipe( pipe_slow ); %} // fast string equals -instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3, - rcx_RegI tmp4, rax_RegI result, rFlagsReg cr) +instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, regD tmp1, regD tmp2, + rbx_RegI tmp3, rax_RegI result, rFlagsReg cr) %{ - match(Set result (StrEquals str1 str2)); - effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); + match(Set result (StrEquals (Binary str1 str2) cnt)); + effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); - format %{ "String Equals $str1,$str2 -> $result // KILL RBX, RCX" %} - ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); + format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} + ins_encode( enc_String_Equals(str1, str2, cnt, tmp1, tmp2, tmp3, result) ); ins_pipe( pipe_slow ); %}