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

src/cpu/x86/vm/x86_64.ad

Print this page

        

*** 543,552 **** --- 543,557 ---- XMM11, XMM11_H, XMM12, XMM12_H, XMM13, XMM13_H, XMM14, XMM14_H, XMM15, XMM15_H); + + // XMM6 and XMM7 could be used as temporary registers for long, float and + // double values for SSE2. + reg_class double_reg6( XMM6,XMM6_H ); + reg_class double_reg7( XMM7,XMM7_H ); %} //----------SOURCE BLOCK------------------------------------------------------- // This is a block of C++ code which provides values, functions, and
*** 3750,3759 **** --- 3755,3765 ---- 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);
*** 3760,3827 **** masm.cmov(Assembler::lessEqual, rsi, rcx); // Is the minimum length zero? masm.bind(RCX_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.negptr(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.increment(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, 8); // That's it masm.bind(DONE_LABEL); %} ! enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI 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); --- 3766,4077 ---- masm.cmov(Assembler::lessEqual, rsi, rcx); // Is the minimum length zero? masm.bind(RCX_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.negptr(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.addptr(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.negptr(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.increment(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, 8); // That's it masm.bind(DONE_LABEL); %} ! 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.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); + + // Substr count saved at sp + // Substr saved at sp+8 + // String saved at sp+16 + + // Prep to load substr for scan + masm.bind(LOAD_SUBSTR); + masm.movptr(rdi, Address(rsp, 8)); + masm.movl(rax, Address(rsp, 0)); + + // Load substr + masm.bind(PREP_FOR_SCAN); + masm.movdqu(xmm6, Address(rdi, 0)); + masm.addq(rdx, 8); // prime the loop + masm.subptr(rsi, 16); + + + // Scan string for substr in 16-byte vectors + masm.bind(SCAN_TO_SUBSTR); + masm.subq(rdx, 8); + masm.addptr(rsi, 16); + masm.pcmpestri(xmm6, Address(rsi, 0), 0x0d); + masm.jcc(Assembler::above, SCAN_TO_SUBSTR); + masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); + + // 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.addq(rdx, 8); // prime the loop + masm.addq(rax, 8); + masm.subptr(rsi, 16); + masm.subptr(rdi, 16); + + // Scan 16-byte vectors of string and substr + masm.bind(SCAN_SUBSTR); + masm.subq(rax, 8); + masm.subq(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, 16)); + 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, 24); + + masm.bind(DONE); + %} + + 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.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); + + 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.negptr(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.addptr(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.negptr(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.addptr(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_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, regD6 tmp3, regD7 tmp4, rcx_RegI 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);
*** 3829,3893 **** int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); // Check the input args masm.cmpq(ary1Reg, ary2Reg); ! masm.jcc(Assembler::equal, TRUE_LABEL); masm.testq(ary1Reg, ary1Reg); ! masm.jcc(Assembler::zero, FALSE_LABEL); masm.testq(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.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); ! masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); ! masm.negq(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.incrementq(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_rethrow() %{ cbuf.set_inst_mark(); --- 4079,4170 ---- int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); // Check the input args masm.cmpq(ary1Reg, ary2Reg); ! masm.jccb(Assembler::equal, TRUE_LABEL); masm.testq(ary1Reg, ary1Reg); ! masm.jccb(Assembler::zero, FALSE_LABEL); masm.testq(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 address ! 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.negptr(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.addptr(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); //if tmp2 == 0, only compare char ! 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.negptr(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.addptr(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_rethrow() %{ cbuf.set_inst_mark();
*** 5154,5174 **** format %{ %} interface(REG_INTER); %} ! // Double register operands ! operand regD() ! %{ constraint(ALLOC_IN_RC(double_reg)); match(RegD); ! format %{ %} interface(REG_INTER); %} //----------Memory Operands---------------------------------------------------- // Direct Memory Operand // operand direct(immP addr) // %{ // match(addr); --- 5431,5467 ---- format %{ %} interface(REG_INTER); %} ! // XMM Double register operands ! operand regD() %{ constraint(ALLOC_IN_RC(double_reg)); match(RegD); ! match(regD6); ! match(regD7); format %{ %} interface(REG_INTER); %} + // XMM6 double register operands + operand regD6(regD reg) %{ + constraint(ALLOC_IN_RC(double_reg6)); + match(reg); + format %{ "XMM6" %} + interface(REG_INTER); + %} + // XMM7 double register operands + operand regD7(regD reg) %{ + constraint(ALLOC_IN_RC(double_reg7)); + match(reg); + + format %{ "XMM7" %} + interface(REG_INTER); + %} + //----------Memory Operands---------------------------------------------------- // Direct Memory Operand // operand direct(immP addr) // %{ // match(addr);
*** 11135,11164 **** Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos ins_pipe(pipe_slow); %} instruct string_compare(rdi_RegP str1, rsi_RegP str2, rax_RegI tmp1, ! rbx_RegI tmp2, rcx_RegI result, rFlagsReg 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 // XXX KILL RAX, RBX" %} ins_encode( enc_String_Compare() ); ins_pipe( pipe_slow ); %} // fast array equals instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, ! rbx_RegI tmp2, rcx_RegI result, rFlagsReg 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 RAX, RBX" %} ! ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) ); ins_pipe( pipe_slow ); %} //----------Control Flow Instructions------------------------------------------ // Signed compare Instructions --- 11428,11477 ---- Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos ins_pipe(pipe_slow); %} instruct string_compare(rdi_RegP str1, rsi_RegP str2, rax_RegI tmp1, ! rbx_RegI tmp2, regD6 tmp3, regD7 tmp4, rcx_RegI result, rFlagsReg 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 // XXX KILL RAX, RBX" %} ins_encode( enc_String_Compare() ); ins_pipe( pipe_slow ); %} + instruct string_indexof(rsi_RegP str1,rdi_RegP str2, rax_RegI tmp1, rcx_RegI tmp2, rdx_RegI tmp3, regD6 tmp4, rbx_RegI result, rFlagsReg 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 string equals + instruct string_equals(rdi_RegP str1, rsi_RegP str2, rbx_RegI tmp1, rcx_RegI tmp2, regD6 tmp3, regD7 tmp4, rax_RegI result, rFlagsReg 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 ); + %} + // fast array equals instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, ! rbx_RegI tmp2, regD6 tmp3, regD7 tmp4, rcx_RegI result, rFlagsReg 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 RAX, RBX" %} ! 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_64.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File