1.1 --- a/src/cpu/x86/vm/x86_32.ad Mon Sep 14 09:49:54 2009 -0700 1.2 +++ b/src/cpu/x86/vm/x86_32.ad Mon Sep 14 12:14:20 2009 -0700 1.3 @@ -3701,458 +3701,6 @@ 1.4 } 1.5 %} 1.6 1.7 - enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 1.8 - eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{ 1.9 - Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL, 1.10 - POP_LABEL, DONE_LABEL, CONT_LABEL, 1.11 - WHILE_HEAD_LABEL; 1.12 - MacroAssembler masm(&cbuf); 1.13 - 1.14 - XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); 1.15 - XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg); 1.16 - 1.17 - // Get the first character position in both strings 1.18 - // [8] char array, [12] offset, [16] count 1.19 - int value_offset = java_lang_String::value_offset_in_bytes(); 1.20 - int offset_offset = java_lang_String::offset_offset_in_bytes(); 1.21 - int count_offset = java_lang_String::count_offset_in_bytes(); 1.22 - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 1.23 - 1.24 - masm.movptr(rax, Address(rsi, value_offset)); 1.25 - masm.movl(rcx, Address(rsi, offset_offset)); 1.26 - masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); 1.27 - masm.movptr(rbx, Address(rdi, value_offset)); 1.28 - masm.movl(rcx, Address(rdi, offset_offset)); 1.29 - masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); 1.30 - 1.31 - // Compute the minimum of the string lengths(rsi) and the 1.32 - // difference of the string lengths (stack) 1.33 - 1.34 - if (VM_Version::supports_cmov()) { 1.35 - masm.movl(rdi, Address(rdi, count_offset)); 1.36 - masm.movl(rsi, Address(rsi, count_offset)); 1.37 - masm.movl(rcx, rdi); 1.38 - masm.subl(rdi, rsi); 1.39 - masm.push(rdi); 1.40 - masm.cmovl(Assembler::lessEqual, rsi, rcx); 1.41 - } else { 1.42 - masm.movl(rdi, Address(rdi, count_offset)); 1.43 - masm.movl(rcx, Address(rsi, count_offset)); 1.44 - masm.movl(rsi, rdi); 1.45 - masm.subl(rdi, rcx); 1.46 - masm.push(rdi); 1.47 - masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL); 1.48 - masm.movl(rsi, rcx); 1.49 - // rsi holds min, rcx is unused 1.50 - } 1.51 - 1.52 - // Is the minimum length zero? 1.53 - masm.bind(ECX_GOOD_LABEL); 1.54 - masm.testl(rsi, rsi); 1.55 - masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); 1.56 - 1.57 - // Load first characters 1.58 - masm.load_unsigned_short(rcx, Address(rbx, 0)); 1.59 - masm.load_unsigned_short(rdi, Address(rax, 0)); 1.60 - 1.61 - // Compare first characters 1.62 - masm.subl(rcx, rdi); 1.63 - masm.jcc(Assembler::notZero, POP_LABEL); 1.64 - masm.decrementl(rsi); 1.65 - masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); 1.66 - 1.67 - { 1.68 - // Check after comparing first character to see if strings are equivalent 1.69 - Label LSkip2; 1.70 - // Check if the strings start at same location 1.71 - masm.cmpptr(rbx,rax); 1.72 - masm.jccb(Assembler::notEqual, LSkip2); 1.73 - 1.74 - // Check if the length difference is zero (from stack) 1.75 - masm.cmpl(Address(rsp, 0), 0x0); 1.76 - masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL); 1.77 - 1.78 - // Strings might not be equivalent 1.79 - masm.bind(LSkip2); 1.80 - } 1.81 - 1.82 - // Advance to next character 1.83 - masm.addptr(rax, 2); 1.84 - masm.addptr(rbx, 2); 1.85 - 1.86 - if (UseSSE42Intrinsics) { 1.87 - // With SSE4.2, use double quad vector compare 1.88 - Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL; 1.89 - // Setup to compare 16-byte vectors 1.90 - masm.movl(rdi, rsi); 1.91 - masm.andl(rsi, 0xfffffff8); // rsi holds the vector count 1.92 - masm.andl(rdi, 0x00000007); // rdi holds the tail count 1.93 - masm.testl(rsi, rsi); 1.94 - masm.jccb(Assembler::zero, COMPARE_TAIL); 1.95 - 1.96 - masm.lea(rax, Address(rax, rsi, Address::times_2)); 1.97 - masm.lea(rbx, Address(rbx, rsi, Address::times_2)); 1.98 - masm.negl(rsi); 1.99 - 1.100 - masm.bind(COMPARE_VECTORS); 1.101 - masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2)); 1.102 - masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2)); 1.103 - masm.pxor(tmp1Reg, tmp2Reg); 1.104 - masm.ptest(tmp1Reg, tmp1Reg); 1.105 - masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL); 1.106 - masm.addl(rsi, 8); 1.107 - masm.jcc(Assembler::notZero, COMPARE_VECTORS); 1.108 - masm.jmpb(COMPARE_TAIL); 1.109 - 1.110 - // Mismatched characters in the vectors 1.111 - masm.bind(VECTOR_NOT_EQUAL); 1.112 - masm.lea(rax, Address(rax, rsi, Address::times_2)); 1.113 - masm.lea(rbx, Address(rbx, rsi, Address::times_2)); 1.114 - masm.movl(rdi, 8); 1.115 - 1.116 - // Compare tail (< 8 chars), or rescan last vectors to 1.117 - // find 1st mismatched characters 1.118 - masm.bind(COMPARE_TAIL); 1.119 - masm.testl(rdi, rdi); 1.120 - masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL); 1.121 - masm.movl(rsi, rdi); 1.122 - // Fallthru to tail compare 1.123 - } 1.124 - 1.125 - //Shift rax, and rbx, to the end of the arrays, negate min 1.126 - masm.lea(rax, Address(rax, rsi, Address::times_2, 0)); 1.127 - masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0)); 1.128 - masm.negl(rsi); 1.129 - 1.130 - // Compare the rest of the characters 1.131 - masm.bind(WHILE_HEAD_LABEL); 1.132 - masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0)); 1.133 - masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0)); 1.134 - masm.subl(rcx, rdi); 1.135 - masm.jccb(Assembler::notZero, POP_LABEL); 1.136 - masm.incrementl(rsi); 1.137 - masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); 1.138 - 1.139 - // Strings are equal up to min length. Return the length difference. 1.140 - masm.bind(LENGTH_DIFF_LABEL); 1.141 - masm.pop(rcx); 1.142 - masm.jmpb(DONE_LABEL); 1.143 - 1.144 - // Discard the stored length difference 1.145 - masm.bind(POP_LABEL); 1.146 - masm.addptr(rsp, 4); 1.147 - 1.148 - // That's it 1.149 - masm.bind(DONE_LABEL); 1.150 - %} 1.151 - 1.152 - enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 1.153 - eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{ 1.154 - Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR; 1.155 - MacroAssembler masm(&cbuf); 1.156 - 1.157 - XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); 1.158 - XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg); 1.159 - 1.160 - int value_offset = java_lang_String::value_offset_in_bytes(); 1.161 - int offset_offset = java_lang_String::offset_offset_in_bytes(); 1.162 - int count_offset = java_lang_String::count_offset_in_bytes(); 1.163 - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 1.164 - 1.165 - // does source == target string? 1.166 - masm.cmpptr(rdi, rsi); 1.167 - masm.jcc(Assembler::equal, RET_TRUE); 1.168 - 1.169 - // get and compare counts 1.170 - masm.movl(rcx, Address(rdi, count_offset)); 1.171 - masm.movl(rax, Address(rsi, count_offset)); 1.172 - masm.cmpl(rcx, rax); 1.173 - masm.jcc(Assembler::notEqual, RET_FALSE); 1.174 - masm.testl(rax, rax); 1.175 - masm.jcc(Assembler::zero, RET_TRUE); 1.176 - 1.177 - // get source string offset and value 1.178 - masm.movptr(rbx, Address(rsi, value_offset)); 1.179 - masm.movl(rax, Address(rsi, offset_offset)); 1.180 - masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset)); 1.181 - 1.182 - // get compare string offset and value 1.183 - masm.movptr(rbx, Address(rdi, value_offset)); 1.184 - masm.movl(rax, Address(rdi, offset_offset)); 1.185 - masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset)); 1.186 - 1.187 - // Set byte count 1.188 - masm.shll(rcx, 1); 1.189 - masm.movl(rax, rcx); 1.190 - 1.191 - if (UseSSE42Intrinsics) { 1.192 - // With SSE4.2, use double quad vector compare 1.193 - Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; 1.194 - // Compare 16-byte vectors 1.195 - masm.andl(rcx, 0xfffffff0); // vector count (in bytes) 1.196 - masm.andl(rax, 0x0000000e); // tail count (in bytes) 1.197 - masm.testl(rcx, rcx); 1.198 - masm.jccb(Assembler::zero, COMPARE_TAIL); 1.199 - masm.lea(rdi, Address(rdi, rcx, Address::times_1)); 1.200 - masm.lea(rsi, Address(rsi, rcx, Address::times_1)); 1.201 - masm.negl(rcx); 1.202 - 1.203 - masm.bind(COMPARE_WIDE_VECTORS); 1.204 - masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1)); 1.205 - masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1)); 1.206 - masm.pxor(tmp1Reg, tmp2Reg); 1.207 - masm.ptest(tmp1Reg, tmp1Reg); 1.208 - masm.jccb(Assembler::notZero, RET_FALSE); 1.209 - masm.addl(rcx, 16); 1.210 - masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); 1.211 - masm.bind(COMPARE_TAIL); 1.212 - masm.movl(rcx, rax); 1.213 - // Fallthru to tail compare 1.214 - } 1.215 - 1.216 - // Compare 4-byte vectors 1.217 - masm.andl(rcx, 0xfffffffc); // vector count (in bytes) 1.218 - masm.andl(rax, 0x00000002); // tail char (in bytes) 1.219 - masm.testl(rcx, rcx); 1.220 - masm.jccb(Assembler::zero, COMPARE_CHAR); 1.221 - masm.lea(rdi, Address(rdi, rcx, Address::times_1)); 1.222 - masm.lea(rsi, Address(rsi, rcx, Address::times_1)); 1.223 - masm.negl(rcx); 1.224 - 1.225 - masm.bind(COMPARE_VECTORS); 1.226 - masm.movl(rbx, Address(rdi, rcx, Address::times_1)); 1.227 - masm.cmpl(rbx, Address(rsi, rcx, Address::times_1)); 1.228 - masm.jccb(Assembler::notEqual, RET_FALSE); 1.229 - masm.addl(rcx, 4); 1.230 - masm.jcc(Assembler::notZero, COMPARE_VECTORS); 1.231 - 1.232 - // Compare trailing char (final 2 bytes), if any 1.233 - masm.bind(COMPARE_CHAR); 1.234 - masm.testl(rax, rax); 1.235 - masm.jccb(Assembler::zero, RET_TRUE); 1.236 - masm.load_unsigned_short(rbx, Address(rdi, 0)); 1.237 - masm.load_unsigned_short(rcx, Address(rsi, 0)); 1.238 - masm.cmpl(rbx, rcx); 1.239 - masm.jccb(Assembler::notEqual, RET_FALSE); 1.240 - 1.241 - masm.bind(RET_TRUE); 1.242 - masm.movl(rax, 1); // return true 1.243 - masm.jmpb(DONE); 1.244 - 1.245 - masm.bind(RET_FALSE); 1.246 - masm.xorl(rax, rax); // return false 1.247 - 1.248 - masm.bind(DONE); 1.249 - %} 1.250 - 1.251 - enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2, 1.252 - eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{ 1.253 - // SSE4.2 version 1.254 - Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR, 1.255 - SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE; 1.256 - MacroAssembler masm(&cbuf); 1.257 - 1.258 - XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); 1.259 - 1.260 - // Get the first character position in both strings 1.261 - // [8] char array, [12] offset, [16] count 1.262 - int value_offset = java_lang_String::value_offset_in_bytes(); 1.263 - int offset_offset = java_lang_String::offset_offset_in_bytes(); 1.264 - int count_offset = java_lang_String::count_offset_in_bytes(); 1.265 - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 1.266 - 1.267 - // Get counts for string and substr 1.268 - masm.movl(rdx, Address(rsi, count_offset)); 1.269 - masm.movl(rax, Address(rdi, count_offset)); 1.270 - // Check for substr count > string count 1.271 - masm.cmpl(rax, rdx); 1.272 - masm.jcc(Assembler::greater, RET_NEG_ONE); 1.273 - 1.274 - // Start the indexOf operation 1.275 - // Get start addr of string 1.276 - masm.movptr(rbx, Address(rsi, value_offset)); 1.277 - masm.movl(rcx, Address(rsi, offset_offset)); 1.278 - masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset)); 1.279 - masm.push(rsi); 1.280 - 1.281 - // Get start addr of substr 1.282 - masm.movptr(rbx, Address(rdi, value_offset)); 1.283 - masm.movl(rcx, Address(rdi, offset_offset)); 1.284 - masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset)); 1.285 - masm.push(rdi); 1.286 - masm.push(rax); 1.287 - masm.jmpb(PREP_FOR_SCAN); 1.288 - 1.289 - // Substr count saved at sp 1.290 - // Substr saved at sp+4 1.291 - // String saved at sp+8 1.292 - 1.293 - // Prep to load substr for scan 1.294 - masm.bind(LOAD_SUBSTR); 1.295 - masm.movptr(rdi, Address(rsp, 4)); 1.296 - masm.movl(rax, Address(rsp, 0)); 1.297 - 1.298 - // Load substr 1.299 - masm.bind(PREP_FOR_SCAN); 1.300 - masm.movdqu(tmp1Reg, Address(rdi, 0)); 1.301 - masm.addl(rdx, 8); // prime the loop 1.302 - masm.subptr(rsi, 16); 1.303 - 1.304 - // Scan string for substr in 16-byte vectors 1.305 - masm.bind(SCAN_TO_SUBSTR); 1.306 - masm.subl(rdx, 8); 1.307 - masm.addptr(rsi, 16); 1.308 - masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d); 1.309 - masm.jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0 1.310 - masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0 1.311 - 1.312 - // Fallthru: found a potential substr 1.313 - 1.314 - // Make sure string is still long enough 1.315 - masm.subl(rdx, rcx); 1.316 - masm.cmpl(rdx, rax); 1.317 - masm.jccb(Assembler::negative, RET_NOT_FOUND); 1.318 - // Compute start addr of substr 1.319 - masm.lea(rsi, Address(rsi, rcx, Address::times_2)); 1.320 - masm.movptr(rbx, rsi); 1.321 - 1.322 - // Compare potential substr 1.323 - masm.addl(rdx, 8); // prime the loop 1.324 - masm.addl(rax, 8); 1.325 - masm.subptr(rsi, 16); 1.326 - masm.subptr(rdi, 16); 1.327 - 1.328 - // Scan 16-byte vectors of string and substr 1.329 - masm.bind(SCAN_SUBSTR); 1.330 - masm.subl(rax, 8); 1.331 - masm.subl(rdx, 8); 1.332 - masm.addptr(rsi, 16); 1.333 - masm.addptr(rdi, 16); 1.334 - masm.movdqu(tmp1Reg, Address(rdi, 0)); 1.335 - masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d); 1.336 - masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 0 1.337 - masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0 1.338 - 1.339 - // Compute substr offset 1.340 - masm.movptr(rsi, Address(rsp, 8)); 1.341 - masm.subptr(rbx, rsi); 1.342 - masm.shrl(rbx, 1); 1.343 - masm.jmpb(CLEANUP); 1.344 - 1.345 - masm.bind(RET_NEG_ONE); 1.346 - masm.movl(rbx, -1); 1.347 - masm.jmpb(DONE); 1.348 - 1.349 - masm.bind(RET_NOT_FOUND); 1.350 - masm.movl(rbx, -1); 1.351 - 1.352 - masm.bind(CLEANUP); 1.353 - masm.addptr(rsp, 12); 1.354 - 1.355 - masm.bind(DONE); 1.356 - %} 1.357 - 1.358 - enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, 1.359 - eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{ 1.360 - Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR; 1.361 - MacroAssembler masm(&cbuf); 1.362 - 1.363 - XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg); 1.364 - XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg); 1.365 - Register ary1Reg = as_Register($ary1$$reg); 1.366 - Register ary2Reg = as_Register($ary2$$reg); 1.367 - Register tmp3Reg = as_Register($tmp3$$reg); 1.368 - Register tmp4Reg = as_Register($tmp4$$reg); 1.369 - Register resultReg = as_Register($result$$reg); 1.370 - 1.371 - int length_offset = arrayOopDesc::length_offset_in_bytes(); 1.372 - int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 1.373 - 1.374 - // Check the input args 1.375 - masm.cmpptr(ary1Reg, ary2Reg); 1.376 - masm.jcc(Assembler::equal, TRUE_LABEL); 1.377 - masm.testptr(ary1Reg, ary1Reg); 1.378 - masm.jcc(Assembler::zero, FALSE_LABEL); 1.379 - masm.testptr(ary2Reg, ary2Reg); 1.380 - masm.jcc(Assembler::zero, FALSE_LABEL); 1.381 - 1.382 - // Check the lengths 1.383 - masm.movl(tmp4Reg, Address(ary1Reg, length_offset)); 1.384 - masm.movl(resultReg, Address(ary2Reg, length_offset)); 1.385 - masm.cmpl(tmp4Reg, resultReg); 1.386 - masm.jcc(Assembler::notEqual, FALSE_LABEL); 1.387 - masm.testl(resultReg, resultReg); 1.388 - masm.jcc(Assembler::zero, TRUE_LABEL); 1.389 - 1.390 - // Load array addrs 1.391 - masm.lea(ary1Reg, Address(ary1Reg, base_offset)); 1.392 - masm.lea(ary2Reg, Address(ary2Reg, base_offset)); 1.393 - 1.394 - // Set byte count 1.395 - masm.shll(tmp4Reg, 1); 1.396 - masm.movl(resultReg, tmp4Reg); 1.397 - 1.398 - if (UseSSE42Intrinsics) { 1.399 - // With SSE4.2, use double quad vector compare 1.400 - Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; 1.401 - // Compare 16-byte vectors 1.402 - masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes) 1.403 - masm.andl(resultReg, 0x0000000e); // tail count (in bytes) 1.404 - masm.testl(tmp4Reg, tmp4Reg); 1.405 - masm.jccb(Assembler::zero, COMPARE_TAIL); 1.406 - masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1)); 1.407 - masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1)); 1.408 - masm.negl(tmp4Reg); 1.409 - 1.410 - masm.bind(COMPARE_WIDE_VECTORS); 1.411 - masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1)); 1.412 - masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1)); 1.413 - masm.pxor(tmp1Reg, tmp2Reg); 1.414 - masm.ptest(tmp1Reg, tmp1Reg); 1.415 - 1.416 - masm.jccb(Assembler::notZero, FALSE_LABEL); 1.417 - masm.addl(tmp4Reg, 16); 1.418 - masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); 1.419 - masm.bind(COMPARE_TAIL); 1.420 - masm.movl(tmp4Reg, resultReg); 1.421 - // Fallthru to tail compare 1.422 - } 1.423 - 1.424 - // Compare 4-byte vectors 1.425 - masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes) 1.426 - masm.andl(resultReg, 0x00000002); // tail char (in bytes) 1.427 - masm.testl(tmp4Reg, tmp4Reg); 1.428 - masm.jccb(Assembler::zero, COMPARE_CHAR); 1.429 - masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1)); 1.430 - masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1)); 1.431 - masm.negl(tmp4Reg); 1.432 - 1.433 - masm.bind(COMPARE_VECTORS); 1.434 - masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1)); 1.435 - masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1)); 1.436 - masm.jccb(Assembler::notEqual, FALSE_LABEL); 1.437 - masm.addl(tmp4Reg, 4); 1.438 - masm.jcc(Assembler::notZero, COMPARE_VECTORS); 1.439 - 1.440 - // Compare trailing char (final 2 bytes), if any 1.441 - masm.bind(COMPARE_CHAR); 1.442 - masm.testl(resultReg, resultReg); 1.443 - masm.jccb(Assembler::zero, TRUE_LABEL); 1.444 - masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0)); 1.445 - masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0)); 1.446 - masm.cmpl(tmp3Reg, tmp4Reg); 1.447 - masm.jccb(Assembler::notEqual, FALSE_LABEL); 1.448 - 1.449 - masm.bind(TRUE_LABEL); 1.450 - masm.movl(resultReg, 1); // return true 1.451 - masm.jmpb(DONE); 1.452 - 1.453 - masm.bind(FALSE_LABEL); 1.454 - masm.xorl(resultReg, resultReg); // return false 1.455 - 1.456 - // That's it 1.457 - masm.bind(DONE); 1.458 - %} 1.459 1.460 enc_class enc_pop_rdx() %{ 1.461 emit_opcode(cbuf,0x5A); 1.462 @@ -12718,48 +12266,64 @@ 1.463 ins_pipe( pipe_slow ); 1.464 %} 1.465 1.466 -instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 1.467 - eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{ 1.468 - match(Set result (StrComp str1 str2)); 1.469 - effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 1.470 - //ins_cost(300); 1.471 - 1.472 - format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %} 1.473 - ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 1.474 +instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2, 1.475 + eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{ 1.476 + match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 1.477 + effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 1.478 + 1.479 + format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %} 1.480 + ins_encode %{ 1.481 + __ string_compare($str1$$Register, $str2$$Register, 1.482 + $cnt1$$Register, $cnt2$$Register, $result$$Register, 1.483 + $tmp1$$XMMRegister, $tmp2$$XMMRegister); 1.484 + %} 1.485 ins_pipe( pipe_slow ); 1.486 %} 1.487 1.488 // fast string equals 1.489 -instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 1.490 - eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ 1.491 - match(Set result (StrEquals str1 str2)); 1.492 - effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 1.493 - 1.494 - format %{ "String Equals $str1,$str2 -> $result // KILL EBX, ECX" %} 1.495 - ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) ); 1.496 - ins_pipe( pipe_slow ); 1.497 -%} 1.498 - 1.499 -instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2, 1.500 - eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{ 1.501 +instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result, 1.502 + regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{ 1.503 + match(Set result (StrEquals (Binary str1 str2) cnt)); 1.504 + effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 1.505 + 1.506 + format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 1.507 + ins_encode %{ 1.508 + __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 1.509 + $cnt$$Register, $result$$Register, $tmp3$$Register, 1.510 + $tmp1$$XMMRegister, $tmp2$$XMMRegister); 1.511 + %} 1.512 + ins_pipe( pipe_slow ); 1.513 +%} 1.514 + 1.515 +instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2, 1.516 + eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{ 1.517 predicate(UseSSE42Intrinsics); 1.518 - match(Set result (StrIndexOf str1 str2)); 1.519 - effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); 1.520 - 1.521 - format %{ "String IndexOf $str1,$str2 -> $result // KILL EAX, ECX, EDX" %} 1.522 - ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 1.523 + match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 1.524 + effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr); 1.525 + 1.526 + format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp2, $tmp1" %} 1.527 + ins_encode %{ 1.528 + __ string_indexof($str1$$Register, $str2$$Register, 1.529 + $cnt1$$Register, $cnt2$$Register, $result$$Register, 1.530 + $tmp1$$XMMRegister, $tmp2$$Register); 1.531 + %} 1.532 ins_pipe( pipe_slow ); 1.533 %} 1.534 1.535 // fast array equals 1.536 -instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3, 1.537 - eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ 1.538 +instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result, 1.539 + regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) 1.540 +%{ 1.541 match(Set result (AryEq ary1 ary2)); 1.542 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 1.543 //ins_cost(300); 1.544 1.545 - format %{ "Array Equals $ary1,$ary2 -> $result // KILL EBX, EDX" %} 1.546 - ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) ); 1.547 + format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 1.548 + ins_encode %{ 1.549 + __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 1.550 + $tmp3$$Register, $result$$Register, $tmp4$$Register, 1.551 + $tmp1$$XMMRegister, $tmp2$$XMMRegister); 1.552 + %} 1.553 ins_pipe( pipe_slow ); 1.554 %} 1.555