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