src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6761600 Cdiff src/cpu/x86/vm/x86_32.ad

src/cpu/x86/vm/x86_32.ad

Print this page

        

*** 3738,3813 **** 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.jcc(Assembler::lessEqual, ECX_GOOD_LABEL); masm.movl(rsi, rcx); // rsi holds min, rcx is unused } // Is the minimum length zero? masm.bind(ECX_GOOD_LABEL); masm.testl(rsi, rsi); ! masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); // Load first characters masm.load_unsigned_word(rcx, Address(rbx, 0)); masm.load_unsigned_word(rdi, Address(rax, 0)); // Compare first characters masm.subl(rcx, rdi); ! masm.jcc(Assembler::notZero, POP_LABEL); masm.decrementl(rsi); ! masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); { // 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.jcc(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) masm.cmpl(Address(rsp, 0), 0x0); ! masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL); // Strings might not be equivalent masm.bind(LSkip2); } ! // Shift rax, and rbx, to the end of the arrays, negate min ! masm.lea(rax, Address(rax, rsi, Address::times_2, 2)); ! masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2)); masm.negl(rsi); // Compare the rest of the characters masm.bind(WHILE_HEAD_LABEL); masm.load_unsigned_word(rcx, Address(rbx, rsi, Address::times_2, 0)); masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); masm.subl(rcx, rdi); ! masm.jcc(Assembler::notZero, POP_LABEL); masm.incrementl(rsi); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. masm.bind(LENGTH_DIFF_LABEL); masm.pop(rcx); ! masm.jmp(DONE_LABEL); // Discard the stored length difference masm.bind(POP_LABEL); masm.addptr(rsp, 4); // That's it masm.bind(DONE_LABEL); %} ! enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result) %{ ! Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP; MacroAssembler masm(&cbuf); Register ary1Reg = as_Register($ary1$$reg); Register ary2Reg = as_Register($ary2$$reg); Register tmp1Reg = as_Register($tmp1$$reg); Register tmp2Reg = as_Register($tmp2$$reg); Register resultReg = as_Register($result$$reg); --- 3738,4056 ---- 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 } // Is the minimum length zero? masm.bind(ECX_GOOD_LABEL); masm.testl(rsi, rsi); ! masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL); // Load first characters masm.load_unsigned_word(rcx, Address(rbx, 0)); masm.load_unsigned_word(rdi, Address(rax, 0)); // Compare first characters masm.subl(rcx, rdi); ! masm.jccb(Assembler::notZero, POP_LABEL); masm.decrementl(rsi); ! masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL); { // 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.jccb(Assembler::notEqual, LSkip2); // Check if the length difference is zero (from stack) masm.cmpl(Address(rsp, 0), 0x0); ! masm.jccb(Assembler::equal, LENGTH_DIFF_LABEL); // Strings might not be equivalent masm.bind(LSkip2); } ! // Advance to next character ! masm.addptr(rax, 2); ! masm.addptr(rbx, 2); ! ! if (UseSSE >=4 && 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.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.bind(COMPARE_VECTORS); + masm.movdqu(xmm6, Address(rax, rsi, Address::times_2)); + masm.movdqu(xmm7, Address(rbx, rsi, Address::times_2)); + masm.pxor(xmm6, xmm7); + masm.ptest(xmm6, xmm6); + masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL); + masm.addl(rsi, 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); + + // Compare tail (< 8 chars), or rescan last vectors to + // find 1st mismatched characters + masm.bind(COMPARE_TAIL); + masm.testl(rdi, rdi); + masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL); + masm.movl(rsi, rdi); + // 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); + // Compare the rest of the characters masm.bind(WHILE_HEAD_LABEL); masm.load_unsigned_word(rcx, Address(rbx, rsi, Address::times_2, 0)); masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); masm.subl(rcx, rdi); ! masm.jccb(Assembler::notZero, POP_LABEL); masm.incrementl(rsi); masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); // Strings are equal up to min length. Return the length difference. masm.bind(LENGTH_DIFF_LABEL); masm.pop(rcx); ! masm.jmpb(DONE_LABEL); // Discard the stored length difference masm.bind(POP_LABEL); masm.addptr(rsp, 4); // That's it masm.bind(DONE_LABEL); %} ! enc_class enc_String_Equals() %{ ! Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR; MacroAssembler masm(&cbuf); + 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? + masm.cmpptr(rdi, rsi); + masm.jccb(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.jccb(Assembler::notEqual, RET_FALSE); + masm.testl(rax, rax); + masm.jccb(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); + + if (UseSSE >=4 && UseSSE42Intrinsics) { + // With SSE4.2, use double quad vector compare + Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; + // Compare 16-byte vectors + masm.andl(rcx, 0xfffffff0); // vector count (in bytes) + masm.andl(rax, 0x0000000e); // tail count (in bytes) + masm.testl(rcx, rcx); + masm.jccb(Assembler::zero, COMPARE_TAIL); + masm.lea(rdi, Address(rdi, rcx, Address::times_1)); + masm.lea(rsi, Address(rsi, rcx, Address::times_1)); + masm.negl(rcx); + + masm.bind(COMPARE_WIDE_VECTORS); + masm.movdqu(xmm6, Address(rdi, rcx, Address::times_1)); + masm.movdqu(xmm7, Address(rsi, rcx, Address::times_1)); + masm.pxor(xmm6, xmm7); + masm.ptest(xmm6, xmm6); + masm.jccb(Assembler::notZero, RET_FALSE); + masm.addl(rcx, 16); + masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); + masm.bind(COMPARE_TAIL); + masm.movl(rcx, rax); + // Fallthru to tail compare + } + + // Compare 4-byte vectors + masm.andl(rcx, 0xfffffffc); // vector count (in bytes) + masm.andl(rax, 0x00000002); // tail char (in bytes) + masm.testl(rcx, rcx); + masm.jccb(Assembler::zero, COMPARE_CHAR); + masm.lea(rdi, Address(rdi, rcx, Address::times_1)); + masm.lea(rsi, Address(rsi, rcx, Address::times_1)); + masm.negl(rcx); + + masm.bind(COMPARE_VECTORS); + masm.movl(rbx, Address(rdi, rcx, Address::times_1)); + masm.cmpl(rbx, Address(rsi, rcx, Address::times_1)); + masm.jccb(Assembler::notEqual, RET_FALSE); + masm.addl(rcx, 4); + masm.jcc(Assembler::notZero, COMPARE_VECTORS); + + // Compare trailing char (final 2 bytes), if any + masm.bind(COMPARE_CHAR); + masm.testl(rax, rax); + masm.jccb(Assembler::zero, RET_TRUE); + masm.load_unsigned_word(rbx, Address(rdi, 0)); + masm.load_unsigned_word(rcx, Address(rsi, 0)); + masm.cmpl(rbx, rcx); + masm.jccb(Assembler::notEqual, RET_FALSE); + + masm.bind(RET_TRUE); + masm.movl(rax, 1); // return true + masm.jmpb(DONE); + + masm.bind(RET_FALSE); + masm.xorl(rax, rax); // return false + + masm.bind(DONE); + %} + + enc_class enc_String_IndexOf() %{ + // SSE4.2 version + Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR, + SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE; + MacroAssembler masm(&cbuf); + + // 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.jccb(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); + + // Substr count saved at sp + // Substr saved at sp+4 + // String saved at sp+8 + + // Prep to load substr for scan + masm.bind(LOAD_SUBSTR); + masm.movptr(rdi, Address(rsp, 4)); + masm.movl(rax, Address(rsp, 0)); + + // Load substr + masm.bind(PREP_FOR_SCAN); + masm.movdqu(xmm6, Address(rdi, 0)); + masm.addl(rdx, 8); // prime the loop + masm.subptr(rsi, 16); + + // Scan string for substr in 16-byte vectors + masm.bind(SCAN_TO_SUBSTR); + masm.subl(rdx, 8); + masm.addptr(rsi, 16); + masm.pcmpestri(xmm6, Address(rsi, 0), 0x0d); + masm.jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0 + masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0 + + // Fallthru: found a potential substr + + // Make sure string is still long enough + masm.subl(rdx, rcx); + masm.cmpl(rdx, rax); + masm.jccb(Assembler::negative, RET_NOT_FOUND); + // Compute start addr of substr + masm.lea(rsi, Address(rsi, rcx, Address::times_2)); + masm.movptr(rbx, rsi); + + // Compare potential substr + masm.addl(rdx, 8); // prime the loop + masm.addl(rax, 8); + masm.subptr(rsi, 16); + masm.subptr(rdi, 16); + + // Scan 16-byte vectors of string and substr + masm.bind(SCAN_SUBSTR); + masm.subl(rax, 8); + masm.subl(rdx, 8); + masm.addptr(rsi, 16); + masm.addptr(rdi, 16); + masm.movdqu(xmm6, Address(rdi, 0)); + masm.pcmpestri(xmm6, Address(rsi, 0), 0x0d); + masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 0 + masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0 + + // Compute substr offset + masm.movptr(rsi, Address(rsp, 8)); + masm.subptr(rbx, rsi); + masm.shrl(rbx, 1); + masm.jmpb(CLEANUP); + + masm.bind(RET_NEG_ONE); + masm.movl(rbx, -1); + masm.jmpb(DONE); + + masm.bind(RET_NOT_FOUND); + masm.movl(rbx, -1); + + masm.bind(CLEANUP); + masm.addptr(rsp, 12); + + masm.bind(DONE); + %} + + + enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, eBXRegI tmp1, eDXRegI tmp2, regXD6 tmp3, regXD7 tmp5, eAXRegI result) %{ + Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR; + MacroAssembler masm(&cbuf); + Register ary1Reg = as_Register($ary1$$reg); Register ary2Reg = as_Register($ary2$$reg); Register tmp1Reg = as_Register($tmp1$$reg); Register tmp2Reg = as_Register($tmp2$$reg); Register resultReg = as_Register($result$$reg);
*** 3814,3879 **** int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); // Check the input args ! masm.cmpl(ary1Reg, ary2Reg); ! masm.jcc(Assembler::equal, TRUE_LABEL); ! masm.testl(ary1Reg, ary1Reg); ! masm.jcc(Assembler::zero, FALSE_LABEL); ! masm.testl(ary2Reg, ary2Reg); ! masm.jcc(Assembler::zero, FALSE_LABEL); // Check the lengths masm.movl(tmp2Reg, Address(ary1Reg, length_offset)); masm.movl(resultReg, Address(ary2Reg, length_offset)); masm.cmpl(tmp2Reg, resultReg); ! masm.jcc(Assembler::notEqual, FALSE_LABEL); masm.testl(resultReg, resultReg); ! masm.jcc(Assembler::zero, TRUE_LABEL); ! // Get the number of 4 byte vectors to compare ! masm.shrl(resultReg, 1); ! // Check for odd-length arrays ! masm.andl(tmp2Reg, 1); masm.testl(tmp2Reg, tmp2Reg); ! masm.jcc(Assembler::zero, COMPARE_LOOP_HDR); ! // Compare 2-byte "tail" at end of arrays ! masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); ! masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); ! masm.cmpl(tmp1Reg, tmp2Reg); ! masm.jcc(Assembler::notEqual, FALSE_LABEL); ! masm.testl(resultReg, resultReg); ! masm.jcc(Assembler::zero, TRUE_LABEL); ! // Setup compare loop ! masm.bind(COMPARE_LOOP_HDR); ! // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays ! masm.leal(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); ! masm.leal(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); ! masm.negl(resultReg); ! // 4-byte-wide compare loop ! masm.bind(COMPARE_LOOP); ! masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0)); ! masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0)); ! masm.cmpl(ary1Reg, ary2Reg); ! masm.jcc(Assembler::notEqual, FALSE_LABEL); ! masm.increment(resultReg); ! masm.jcc(Assembler::notZero, COMPARE_LOOP); masm.bind(TRUE_LABEL); masm.movl(resultReg, 1); // return true ! masm.jmp(DONE_LABEL); masm.bind(FALSE_LABEL); masm.xorl(resultReg, resultReg); // return false // That's it ! masm.bind(DONE_LABEL); %} enc_class enc_pop_rdx() %{ emit_opcode(cbuf,0x5A); %} --- 4057,4150 ---- int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); // Check the input args ! masm.cmpptr(ary1Reg, ary2Reg); ! masm.jccb(Assembler::equal, TRUE_LABEL); ! masm.testptr(ary1Reg, ary1Reg); ! masm.jccb(Assembler::zero, FALSE_LABEL); ! masm.testptr(ary2Reg, ary2Reg); ! masm.jccb(Assembler::zero, FALSE_LABEL); // Check the lengths masm.movl(tmp2Reg, Address(ary1Reg, length_offset)); masm.movl(resultReg, Address(ary2Reg, length_offset)); masm.cmpl(tmp2Reg, resultReg); ! masm.jccb(Assembler::notEqual, FALSE_LABEL); masm.testl(resultReg, resultReg); ! masm.jccb(Assembler::zero, TRUE_LABEL); ! // Load array addrs ! masm.lea(ary1Reg, Address(ary1Reg, base_offset)); ! masm.lea(ary2Reg, Address(ary2Reg, base_offset)); ! // Set byte count ! masm.shll(tmp2Reg, 1); ! masm.movl(resultReg, tmp2Reg); ! ! ! if (UseSSE >=4 && UseSSE42Intrinsics) { ! // With SSE4.2, use double quad vector compare ! Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; ! // Compare 16-byte vectors ! masm.andl(tmp2Reg, 0xfffffff0); // vector count (in bytes) ! masm.andl(resultReg, 0x0000000e); // tail count (in bytes) masm.testl(tmp2Reg, tmp2Reg); ! masm.jccb(Assembler::zero, COMPARE_TAIL); ! masm.lea(ary1Reg, Address(ary1Reg, tmp2Reg, Address::times_1)); ! masm.lea(ary2Reg, Address(ary2Reg, tmp2Reg, Address::times_1)); ! masm.negl(tmp2Reg); ! masm.bind(COMPARE_WIDE_VECTORS); ! masm.movdqu(xmm6, Address(ary1Reg, tmp2Reg, Address::times_1)); ! masm.movdqu(xmm7, Address(ary2Reg, tmp2Reg, Address::times_1)); ! masm.pxor(xmm6, xmm7); ! masm.ptest(xmm6, xmm6); ! masm.jccb(Assembler::notZero, FALSE_LABEL); ! masm.addl(tmp2Reg, 16); ! masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); ! masm.bind(COMPARE_TAIL); ! masm.movl(tmp2Reg, resultReg); ! // Fallthru to tail compare ! } ! // Compare 4-byte vectors ! masm.andl(tmp2Reg, 0xfffffffc); // vector count (in bytes) ! masm.andl(resultReg, 0x00000002); // tail char (in bytes) ! masm.testl(tmp2Reg, tmp2Reg); ! masm.jccb(Assembler::zero, COMPARE_CHAR); ! masm.lea(ary1Reg, Address(ary1Reg, tmp2Reg, Address::times_1)); ! masm.lea(ary2Reg, Address(ary2Reg, tmp2Reg, Address::times_1)); ! masm.negl(tmp2Reg); + masm.bind(COMPARE_VECTORS); + masm.movl(tmp1Reg, Address(ary1Reg, tmp2Reg, Address::times_1)); + masm.cmpl(tmp1Reg, Address(ary2Reg, tmp2Reg, Address::times_1)); + masm.jccb(Assembler::notEqual, FALSE_LABEL); + masm.addl(tmp2Reg, 4); + masm.jcc(Assembler::notZero, COMPARE_VECTORS); + + // Compare trailing char (final 2 bytes), if any + masm.bind(COMPARE_CHAR); + masm.testl(resultReg, resultReg); + masm.jccb(Assembler::zero, TRUE_LABEL); + masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, 0)); + masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, 0)); + masm.cmpl(tmp1Reg, tmp2Reg); + masm.jccb(Assembler::notEqual, FALSE_LABEL); + masm.bind(TRUE_LABEL); masm.movl(resultReg, 1); // return true ! masm.jmpb(DONE); masm.bind(FALSE_LABEL); masm.xorl(resultReg, resultReg); // return false // That's it ! masm.bind(DONE); %} enc_class enc_pop_rdx() %{ emit_opcode(cbuf,0x5A); %}
*** 11900,11911 **** format %{ "PXOR $dst,$dst\t! replicate2F" %} ins_encode( pxor(dst, dst)); ins_pipe( fpu_reg_reg ); %} - - // ======================================================================= // fast clearing of an array instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ match(Set dummy (ClearArray cnt base)); --- 12171,12180 ----
*** 11918,11945 **** OpcRegReg(0x33,EAX,EAX), Opcode(0xF3), Opcode(0xAB) ); ins_pipe( pipe_slow ); %} ! instruct string_compare(eDIRegP str1, eSIRegP str2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{ match(Set result (StrComp str1 str2)); ! effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr); //ins_cost(300); ! format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %} ins_encode( enc_String_Compare() ); ins_pipe( pipe_slow ); %} // fast array equals ! instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{ match(Set result (AryEq ary1 ary2)); ! effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr); //ins_cost(300); ! format %{ "Array Equals $ary1,$ary2 -> $result // KILL EAX, EBX" %} ! ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) ); ins_pipe( pipe_slow ); %} //----------Control Flow Instructions------------------------------------------ // Signed compare Instructions --- 12187,12234 ---- OpcRegReg(0x33,EAX,EAX), Opcode(0xF3), Opcode(0xAB) ); ins_pipe( pipe_slow ); %} ! instruct string_compare(eDIRegP str1, eSIRegP str2, eAXRegI tmp1, eBXRegI tmp2, regXD6 tmp3, regXD7 tmp4, eCXRegI result, eFlagsReg cr) %{ match(Set result (StrComp str1 str2)); ! effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); //ins_cost(300); ! format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX, XMM6, XMM7" %} ins_encode( enc_String_Compare() ); ins_pipe( pipe_slow ); %} + // fast string equals + instruct string_equals(eDIRegP str1, eSIRegP str2, eBXRegI tmp1, eCXRegI tmp2, regXD6 tmp3, regXD7 tmp4, eAXRegI result, eFlagsReg cr) %{ + match(Set result (StrEquals str1 str2)); + effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); + + format %{ "String Equals $str1,$str2 -> $result // KILL EBX, ECX, EDX, XMM6, XMM7" %} + ins_encode( enc_String_Equals() ); + ins_pipe( pipe_slow ); + %} + + instruct string_indexof(eSIRegP str1, eDIRegP str2, eAXRegI tmp1, eCXRegI tmp2, eDXRegI tmp3, regXD6 tmp4, eBXRegI result, eFlagsReg cr) %{ + predicate(UseSSE >=4 && UseSSE42Intrinsics); + match(Set result (StrIndexOf str1 str2)); + effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); + + format %{ "String IndexOf $str1,$str2 -> $result // KILL EAX, ECX, EDX, XMM6" %} + ins_encode( enc_String_IndexOf() ); + ins_pipe( pipe_slow ); + %} + // fast array equals ! instruct array_equals(eDIRegP ary1, eSIRegP ary2, eBXRegI tmp1, eDXRegI tmp2, regXD6 tmp3, regXD7 tmp4, eAXRegI result, eFlagsReg cr) %{ match(Set result (AryEq ary1 ary2)); ! effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); //ins_cost(300); ! format %{ "Array Equals $ary1,$ary2 -> $result // KILL EBX, EDX, XMM6, XMM7" %} ! ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) ); ins_pipe( pipe_slow ); %} //----------Control Flow Instructions------------------------------------------ // Signed compare Instructions
src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File