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