--- old/src/cpu/x86/vm/x86_32.ad Tue Aug 18 19:06:15 2009 +++ new/src/cpu/x86/vm/x86_32.ad Tue Aug 18 19:06:14 2009 @@ -3701,64 +3701,40 @@ } %} - enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, - eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{ + enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, eBXRegI cnt1, eAXRegI cnt2, + regXD tmp1, regXD tmp2, eCXRegI result) %{ Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, CONT_LABEL, WHILE_HEAD_LABEL; MacroAssembler masm(&cbuf); - 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.movptr(rax, Address(rsi, value_offset)); - masm.movl(rcx, Address(rsi, offset_offset)); - masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); - masm.movptr(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) + masm.movl(rcx, rbx); + masm.subl(rbx, rax); + masm.push(rbx); if (VM_Version::supports_cmov()) { - 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.cmovl(Assembler::lessEqual, rsi, rcx); + masm.cmovl(Assembler::lessEqual, rax, rcx); } else { - masm.movl(rdi, Address(rdi, count_offset)); - masm.movl(rcx, Address(rsi, count_offset)); - masm.movl(rsi, rdi); - masm.subl(rdi, rcx); - masm.push(rdi); - masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL); - masm.movl(rsi, rcx); - // rsi holds min, rcx is unused + masm.jccb(Assembler::greater, ECX_GOOD_LABEL); + masm.movl(rax, rcx); } + // rax holds min // Is the minimum length zero? masm.bind(ECX_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); { @@ -3765,7 +3741,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) @@ -3776,61 +3752,61 @@ masm.bind(LSkip2); } - // Advance to next character - masm.addptr(rax, 2); - masm.addptr(rbx, 2); + // Advance to next character + 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.negl(rsi); + masm.lea(rsi, Address(rsi, rax, Address::times_2)); + masm.lea(rdi, Address(rdi, rax, Address::times_2)); + masm.negl(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.addl(rsi, 8); + masm.addl(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.negl(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.negl(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.incrementl(rsi); + masm.increment(rax); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. @@ -3846,8 +3822,8 @@ masm.bind(DONE_LABEL); %} - enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, - eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{ + enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, regXD tmp1, + regXD tmp2, eBXRegI tmp3, eAXRegI result) %{ Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR; MacroAssembler masm(&cbuf); @@ -3854,33 +3830,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.movptr(rbx, Address(rsi, value_offset)); - masm.movl(rax, Address(rsi, offset_offset)); - masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset)); - - // get compare string offset and value - masm.movptr(rbx, Address(rdi, value_offset)); - masm.movl(rax, Address(rdi, offset_offset)); - masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset)); - // Set byte count masm.shll(rcx, 1); masm.movl(rax, rcx); @@ -3945,8 +3902,8 @@ masm.bind(DONE); %} - enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2, - eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{ + enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, eDXRegI cnt1, eAXRegI cnt2, + regXD tmp1, eCXRegI tmp2, eBXRegI result) %{ // SSE4.2 version Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR, SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE; @@ -3954,31 +3911,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.movptr(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.movptr(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); @@ -4002,6 +3939,14 @@ masm.bind(SCAN_TO_SUBSTR); masm.subl(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); // CF == 0 && ZF == 0 masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0 @@ -12718,36 +12663,38 @@ ins_pipe( pipe_slow ); %} -instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, - eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{ - match(Set result (StrComp str1 str2)); - effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); - //ins_cost(300); +instruct string_compare(eDIRegP str1, eSIRegP str2, eBXRegI cnt1, eAXRegI cnt2, + regXD tmp1, regXD tmp2, eCXRegI result, eFlagsReg 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); - format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %} - 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 ); %} + // fast string equals -instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, - eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ - match(Set result (StrEquals str1 str2)); - effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); +instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, regXD tmp1, regXD tmp2, + eBXRegI tmp3, eAXRegI result, eFlagsReg 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 EBX, ECX" %} - ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, 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 ); %} -instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2, - eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{ + +instruct string_indexof(eSIRegP str1, eDIRegP str2, eDXRegI cnt1, eAXRegI cnt2, + regXD tmp1, eCXRegI tmp2, eBXRegI result, eFlagsReg 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 EAX, ECX, EDX" %} - ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); + format %{ "String IndexOf $str1,$str2,$cnt1,$cnt2 -> $result // KILL $tmp2, $tmp1" %} + ins_encode( enc_String_IndexOf(str1, str2, cnt1, cnt2, tmp1, tmp2, result) ); ins_pipe( pipe_slow ); %}