< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.cpp

Print this page
rev 11557 : 8156943: aarch64: string compare does not support CompactStrings
Summary: Implement LL, UL and LU encodings for StrComp
Reviewed-by: aph


 548   bind(cas_label);
 549 
 550   return null_check_offset;
 551 }
 552 
 553 void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) {
 554   assert(UseBiasedLocking, "why call this otherwise?");
 555 
 556   // Check for biased locking unlock case, which is a no-op
 557   // Note: we do not have to check the thread ID for two reasons.
 558   // First, the interpreter checks for IllegalMonitorStateException at
 559   // a higher level. Second, if the bias was revoked while we held the
 560   // lock, the object could not be rebiased toward another thread, so
 561   // the bias bit would be clear.
 562   ldr(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 563   andr(temp_reg, temp_reg, markOopDesc::biased_lock_mask_in_place);
 564   cmp(temp_reg, markOopDesc::biased_lock_pattern);
 565   br(Assembler::EQ, done);
 566 }
 567 
 568 
 569 // added to make this compile
 570 
 571 REGISTER_DEFINITION(Register, noreg);
 572 
 573 static void pass_arg0(MacroAssembler* masm, Register arg) {
 574   if (c_rarg0 != arg ) {
 575     masm->mov(c_rarg0, arg);
 576   }
 577 }
 578 
 579 static void pass_arg1(MacroAssembler* masm, Register arg) {
 580   if (c_rarg1 != arg ) {
 581     masm->mov(c_rarg1, arg);
 582   }
 583 }
 584 
 585 static void pass_arg2(MacroAssembler* masm, Register arg) {
 586   if (c_rarg2 != arg ) {
 587     masm->mov(c_rarg2, arg);
 588   }
 589 }
 590 
 591 static void pass_arg3(MacroAssembler* masm, Register arg) {
 592   if (c_rarg3 != arg ) {


4483       BIND(DO1_SHORT);
4484         mov(result_tmp, cnt2);
4485         lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
4486         sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
4487       BIND(DO1_LOOP);
4488         (this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
4489         cmpw(ch1, ch2);
4490         br(EQ, MATCH);
4491         adds(cnt2_neg, cnt2_neg, str2_chr_size);
4492         br(LT, DO1_LOOP);
4493     }
4494   }
4495   BIND(NOMATCH);
4496     mov(result, -1);
4497     b(DONE);
4498   BIND(MATCH);
4499     add(result, result_tmp, cnt2_neg, ASR, str2_chr_shift);
4500   BIND(DONE);
4501 }
4502 



4503 // Compare strings.
4504 void MacroAssembler::string_compare(Register str1, Register str2,
4505                                     Register cnt1, Register cnt2, Register result,
4506                                     Register tmp1) {

4507   Label LENGTH_DIFF, DONE, SHORT_LOOP, SHORT_STRING,
4508     NEXT_WORD, DIFFERENCE;
4509 



















4510   BLOCK_COMMENT("string_compare {");
4511 





4512   // Compute the minimum of the string lengths and save the difference.
4513   subsw(tmp1, cnt1, cnt2);
4514   cselw(cnt2, cnt1, cnt2, Assembler::LE); // min
4515 
4516   // A very short string
4517   cmpw(cnt2, 4);
4518   br(Assembler::LT, SHORT_STRING);
4519 
4520   // Check if the strings start at the same location.
4521   cmp(str1, str2);
4522   br(Assembler::EQ, LENGTH_DIFF);
4523 
4524   // Compare longwords
4525   {
4526     subw(cnt2, cnt2, 4); // The last longword is a special case
4527 
4528     // Move both string pointers to the last longword of their
4529     // strings, negate the remaining count, and convert it to bytes.
4530     lea(str1, Address(str1, cnt2, Address::uxtw(1)));
4531     lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4532     sub(cnt2, zr, cnt2, LSL, 1);




4533 
4534     // Loop, loading longwords and comparing them into rscratch2.
4535     bind(NEXT_WORD);
4536     ldr(result, Address(str1, cnt2));
4537     ldr(cnt1, Address(str2, cnt2));
4538     adds(cnt2, cnt2, wordSize);
4539     eor(rscratch2, result, cnt1);













4540     cbnz(rscratch2, DIFFERENCE);
4541     br(Assembler::LT, NEXT_WORD);
4542 
4543     // Last longword.  In the case where length == 4 we compare the
4544     // same longword twice, but that's still faster than another
4545     // conditional branch.
4546 





4547     ldr(result, Address(str1));
4548     ldr(cnt1, Address(str2));
4549     eor(rscratch2, result, cnt1);







4550     cbz(rscratch2, LENGTH_DIFF);
4551 
4552     // Find the first different characters in the longwords and
4553     // compute their difference.
4554     bind(DIFFERENCE);
4555     rev(rscratch2, rscratch2);
4556     clz(rscratch2, rscratch2);
4557     andr(rscratch2, rscratch2, -16);
4558     lsrv(result, result, rscratch2);
4559     uxthw(result, result);
4560     lsrv(cnt1, cnt1, rscratch2);
4561     uxthw(cnt1, cnt1);
4562     subw(result, result, cnt1);
4563     b(DONE);
4564   }
4565 
4566   bind(SHORT_STRING);
4567   // Is the minimum length zero?
4568   cbz(cnt2, LENGTH_DIFF);
4569 
4570   bind(SHORT_LOOP);
4571   load_unsigned_short(result, Address(post(str1, 2)));
4572   load_unsigned_short(cnt1, Address(post(str2, 2)));
4573   subw(result, result, cnt1);
4574   cbnz(result, DONE);
4575   sub(cnt2, cnt2, 1);
4576   cbnz(cnt2, SHORT_LOOP);
4577 
4578   // Strings are equal up to min length.  Return the length difference.
4579   bind(LENGTH_DIFF);
4580   mov(result, tmp1);
4581 
4582   // That's it
4583   bind(DONE);
4584 
4585   BLOCK_COMMENT("} string_compare");
4586 }
4587 
4588 // Compare Strings or char/byte arrays.
4589 
4590 // is_string is true iff this is a string comparison.
4591 
4592 // For Strings we're passed the address of the first characters in a1




 548   bind(cas_label);
 549 
 550   return null_check_offset;
 551 }
 552 
 553 void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) {
 554   assert(UseBiasedLocking, "why call this otherwise?");
 555 
 556   // Check for biased locking unlock case, which is a no-op
 557   // Note: we do not have to check the thread ID for two reasons.
 558   // First, the interpreter checks for IllegalMonitorStateException at
 559   // a higher level. Second, if the bias was revoked while we held the
 560   // lock, the object could not be rebiased toward another thread, so
 561   // the bias bit would be clear.
 562   ldr(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 563   andr(temp_reg, temp_reg, markOopDesc::biased_lock_mask_in_place);
 564   cmp(temp_reg, markOopDesc::biased_lock_pattern);
 565   br(Assembler::EQ, done);
 566 }
 567 





 568 static void pass_arg0(MacroAssembler* masm, Register arg) {
 569   if (c_rarg0 != arg ) {
 570     masm->mov(c_rarg0, arg);
 571   }
 572 }
 573 
 574 static void pass_arg1(MacroAssembler* masm, Register arg) {
 575   if (c_rarg1 != arg ) {
 576     masm->mov(c_rarg1, arg);
 577   }
 578 }
 579 
 580 static void pass_arg2(MacroAssembler* masm, Register arg) {
 581   if (c_rarg2 != arg ) {
 582     masm->mov(c_rarg2, arg);
 583   }
 584 }
 585 
 586 static void pass_arg3(MacroAssembler* masm, Register arg) {
 587   if (c_rarg3 != arg ) {


4478       BIND(DO1_SHORT);
4479         mov(result_tmp, cnt2);
4480         lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
4481         sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
4482       BIND(DO1_LOOP);
4483         (this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
4484         cmpw(ch1, ch2);
4485         br(EQ, MATCH);
4486         adds(cnt2_neg, cnt2_neg, str2_chr_size);
4487         br(LT, DO1_LOOP);
4488     }
4489   }
4490   BIND(NOMATCH);
4491     mov(result, -1);
4492     b(DONE);
4493   BIND(MATCH);
4494     add(result, result_tmp, cnt2_neg, ASR, str2_chr_shift);
4495   BIND(DONE);
4496 }
4497 
4498 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
4499 typedef void (MacroAssembler::* uxt_insn)(Register Rd, Register Rn);
4500 
4501 // Compare strings.
4502 void MacroAssembler::string_compare(Register str1, Register str2,
4503                                     Register cnt1, Register cnt2, Register result,
4504                                     Register tmp1,
4505                                     FloatRegister vtmp, FloatRegister vtmpZ, int ae) {
4506   Label LENGTH_DIFF, DONE, SHORT_LOOP, SHORT_STRING,
4507     NEXT_WORD, DIFFERENCE;
4508 
4509   bool isLL = ae == StrIntrinsicNode::LL;
4510   bool isLU = ae == StrIntrinsicNode::LU;
4511   bool isUL = ae == StrIntrinsicNode::UL;
4512 
4513   bool str1_isL = isLL || isLU;
4514   bool str2_isL = isLL || isUL;
4515 
4516   int str1_chr_shift = str1_isL ? 0 : 1;
4517   int str2_chr_shift = str2_isL ? 0 : 1;
4518   int str1_chr_size = str1_isL ? 1 : 2;
4519   int str2_chr_size = str2_isL ? 1 : 2;
4520 
4521   chr_insn str1_load_chr = str1_isL ? (chr_insn)&MacroAssembler::ldrb :
4522                                       (chr_insn)&MacroAssembler::ldrh;
4523   chr_insn str2_load_chr = str2_isL ? (chr_insn)&MacroAssembler::ldrb :
4524                                       (chr_insn)&MacroAssembler::ldrh;
4525   uxt_insn ext_chr = isLL ? (uxt_insn)&MacroAssembler::uxtbw :
4526                             (uxt_insn)&MacroAssembler::uxthw;
4527 
4528   BLOCK_COMMENT("string_compare {");
4529 
4530   // Bizzarely, the counts are passed in bytes, regardless of whether they
4531   // are L or U strings, however the result is always in characters.
4532   if (!str1_isL) asrw(cnt1, cnt1, 1);
4533   if (!str2_isL) asrw(cnt2, cnt2, 1);
4534 
4535   // Compute the minimum of the string lengths and save the difference.
4536   subsw(tmp1, cnt1, cnt2);
4537   cselw(cnt2, cnt1, cnt2, Assembler::LE); // min
4538 
4539   // A very short string
4540   cmpw(cnt2, isLL ? 8:4);
4541   br(Assembler::LT, SHORT_STRING);
4542 
4543   // Check if the strings start at the same location.
4544   cmp(str1, str2);
4545   br(Assembler::EQ, LENGTH_DIFF);
4546 
4547   // Compare longwords
4548   {
4549     subw(cnt2, cnt2, isLL ? 8:4); // The last longword is a special case
4550 
4551     // Move both string pointers to the last longword of their
4552     // strings, negate the remaining count, and convert it to bytes.
4553     lea(str1, Address(str1, cnt2, Address::uxtw(str1_chr_shift)));
4554     lea(str2, Address(str2, cnt2, Address::uxtw(str2_chr_shift)));
4555     if (isLU || isUL) {
4556       sub(cnt1, zr, cnt2, LSL, str1_chr_shift);
4557       eor(vtmpZ, T16B, vtmpZ, vtmpZ);
4558     }
4559     sub(cnt2, zr, cnt2, LSL, str2_chr_shift);
4560 
4561     // Loop, loading longwords and comparing them into rscratch2.
4562     bind(NEXT_WORD);
4563     if (isLU) {
4564       ldrs(vtmp, Address(str1, cnt1));
4565       zip1(vtmp, T8B, vtmp, vtmpZ);
4566       umov(result, vtmp, D, 0);
4567     } else {
4568       ldr(result, Address(str1, isUL ? cnt1:cnt2));
4569     }
4570     if (isUL) {
4571       ldrs(vtmp, Address(str2, cnt2));
4572       zip1(vtmp, T8B, vtmp, vtmpZ);
4573       umov(rscratch1, vtmp, D, 0);
4574     } else {
4575       ldr(rscratch1, Address(str2, cnt2));
4576     }
4577     adds(cnt2, cnt2, isUL ? 4:8);
4578     if (isLU || isUL) add(cnt1, cnt1, isLU ? 4:8);
4579     eor(rscratch2, result, rscratch1);
4580     cbnz(rscratch2, DIFFERENCE);
4581     br(Assembler::LT, NEXT_WORD);
4582 
4583     // Last longword.  In the case where length == 4 we compare the
4584     // same longword twice, but that's still faster than another
4585     // conditional branch.
4586 
4587     if (isLU) {
4588       ldrs(vtmp, Address(str1));
4589       zip1(vtmp, T8B, vtmp, vtmpZ);
4590       umov(result, vtmp, D, 0);
4591     } else {
4592       ldr(result, Address(str1));
4593     }
4594     if (isUL) {
4595       ldrs(vtmp, Address(str2));
4596       zip1(vtmp, T8B, vtmp, vtmpZ);
4597       umov(rscratch1, vtmp, D, 0);
4598     } else {
4599       ldr(rscratch1, Address(str2));
4600     }
4601     eor(rscratch2, result, rscratch1);
4602     cbz(rscratch2, LENGTH_DIFF);
4603 
4604     // Find the first different characters in the longwords and
4605     // compute their difference.
4606     bind(DIFFERENCE);
4607     rev(rscratch2, rscratch2);
4608     clz(rscratch2, rscratch2);
4609     andr(rscratch2, rscratch2, isLL ? -8 : -16);
4610     lsrv(result, result, rscratch2);
4611     (this->*ext_chr)(result, result);
4612     lsrv(rscratch1, rscratch1, rscratch2);
4613     (this->*ext_chr)(rscratch1, rscratch1);
4614     subw(result, result, rscratch1);
4615     b(DONE);
4616   }
4617 
4618   bind(SHORT_STRING);
4619   // Is the minimum length zero?
4620   cbz(cnt2, LENGTH_DIFF);
4621 
4622   bind(SHORT_LOOP);
4623   (this->*str1_load_chr)(result, Address(post(str1, str1_chr_size)));
4624   (this->*str2_load_chr)(cnt1, Address(post(str2, str2_chr_size)));
4625   subw(result, result, cnt1);
4626   cbnz(result, DONE);
4627   sub(cnt2, cnt2, 1);
4628   cbnz(cnt2, SHORT_LOOP);
4629 
4630   // Strings are equal up to min length.  Return the length difference.
4631   bind(LENGTH_DIFF);
4632   mov(result, tmp1);
4633 
4634   // That's it
4635   bind(DONE);
4636 
4637   BLOCK_COMMENT("} string_compare");
4638 }
4639 
4640 // Compare Strings or char/byte arrays.
4641 
4642 // is_string is true iff this is a string comparison.
4643 
4644 // For Strings we're passed the address of the first characters in a1


< prev index next >