< prev index next >

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Print this page
8248238: Adding Windows support to OpenJDK on AArch64

Summary: Adding Windows support for AArch64

Contributed-by: Ludovic Henry <luhenry@microsoft.com>, Monica Beckwith <monica.beckwith@microsoft.com>
Reviewed-by:


 526     sub(cnt1_neg, zr, cnt1, LSL, 1);
 527   BIND(DO1_LOOP);
 528     ldrh(ch1, Address(str1, cnt1_neg));
 529     cmpw(ch, ch1);
 530     br(EQ, MATCH);
 531     adds(cnt1_neg, cnt1_neg, 2);
 532     br(LT, DO1_LOOP);
 533   BIND(NOMATCH);
 534     mov(result, -1);
 535     b(DONE);
 536   BIND(MATCH);
 537     add(result, result_tmp, cnt1_neg, ASR, 1);
 538   BIND(DONE);
 539 }
 540 
 541 // Compare strings.
 542 void C2_MacroAssembler::string_compare(Register str1, Register str2,
 543     Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2,
 544     FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, int ae) {
 545   Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB,
 546       DIFFERENCE, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT,
 547       SHORT_LOOP_START, TAIL_CHECK;
 548 
 549   bool isLL = ae == StrIntrinsicNode::LL;
 550   bool isLU = ae == StrIntrinsicNode::LU;
 551   bool isUL = ae == StrIntrinsicNode::UL;
 552 
 553   // The stub threshold for LL strings is: 72 (64 + 8) chars
 554   // UU: 36 chars, or 72 bytes (valid for the 64-byte large loop with prefetch)
 555   // LU/UL: 24 chars, or 48 bytes (valid for the 16-character loop at least)
 556   const u1 stub_threshold = isLL ? 72 : ((isLU || isUL) ? 24 : 36);
 557 
 558   bool str1_isL = isLL || isLU;
 559   bool str2_isL = isLL || isUL;
 560 
 561   int str1_chr_shift = str1_isL ? 0 : 1;
 562   int str2_chr_shift = str2_isL ? 0 : 1;
 563   int str1_chr_size = str1_isL ? 1 : 2;
 564   int str2_chr_size = str2_isL ? 1 : 2;
 565   int minCharsInWord = isLL ? wordSize : wordSize/2;
 566 


 617       add(cnt1, cnt1, 4);
 618       fmovd(tmp1, vtmp);
 619     } else { // UL case
 620       ldr(tmp1, Address(str1));
 621       ldrs(vtmp, Address(str2));
 622       cmp(cnt2, stub_threshold);
 623       br(GE, STUB);
 624       subw(cnt2, cnt2, 4);
 625       lea(str1, Address(str1, cnt2, Address::uxtw(str1_chr_shift)));
 626       eor(vtmpZ, T16B, vtmpZ, vtmpZ);
 627       lea(str2, Address(str2, cnt2, Address::uxtw(str2_chr_shift)));
 628       sub(cnt1, zr, cnt2, LSL, str1_chr_shift);
 629       zip1(vtmp, T8B, vtmp, vtmpZ);
 630       sub(cnt2, zr, cnt2, LSL, str2_chr_shift);
 631       add(cnt1, cnt1, 8);
 632       fmovd(tmp2, vtmp);
 633     }
 634     adds(cnt2, cnt2, isUL ? 4 : 8);
 635     br(GE, TAIL);
 636     eor(rscratch2, tmp1, tmp2);
 637     cbnz(rscratch2, DIFFERENCE);
 638     // main loop
 639     bind(NEXT_WORD);
 640     if (str1_isL == str2_isL) {
 641       ldr(tmp1, Address(str1, cnt2));
 642       ldr(tmp2, Address(str2, cnt2));
 643       adds(cnt2, cnt2, 8);
 644     } else if (isLU) {
 645       ldrs(vtmp, Address(str1, cnt1));
 646       ldr(tmp2, Address(str2, cnt2));
 647       add(cnt1, cnt1, 4);
 648       zip1(vtmp, T8B, vtmp, vtmpZ);
 649       fmovd(tmp1, vtmp);
 650       adds(cnt2, cnt2, 8);
 651     } else { // UL
 652       ldrs(vtmp, Address(str2, cnt2));
 653       ldr(tmp1, Address(str1, cnt1));
 654       zip1(vtmp, T8B, vtmp, vtmpZ);
 655       add(cnt1, cnt1, 8);
 656       fmovd(tmp2, vtmp);
 657       adds(cnt2, cnt2, 4);
 658     }
 659     br(GE, TAIL);
 660 
 661     eor(rscratch2, tmp1, tmp2);
 662     cbz(rscratch2, NEXT_WORD);
 663     b(DIFFERENCE);
 664     bind(TAIL);
 665     eor(rscratch2, tmp1, tmp2);
 666     cbnz(rscratch2, DIFFERENCE);
 667     // Last longword.  In the case where length == 4 we compare the
 668     // same longword twice, but that's still faster than another
 669     // conditional branch.
 670     if (str1_isL == str2_isL) {
 671       ldr(tmp1, Address(str1));
 672       ldr(tmp2, Address(str2));
 673     } else if (isLU) {
 674       ldrs(vtmp, Address(str1));
 675       ldr(tmp2, Address(str2));
 676       zip1(vtmp, T8B, vtmp, vtmpZ);
 677       fmovd(tmp1, vtmp);
 678     } else { // UL
 679       ldrs(vtmp, Address(str2));
 680       ldr(tmp1, Address(str1));
 681       zip1(vtmp, T8B, vtmp, vtmpZ);
 682       fmovd(tmp2, vtmp);
 683     }
 684     bind(TAIL_CHECK);
 685     eor(rscratch2, tmp1, tmp2);
 686     cbz(rscratch2, DONE);
 687 
 688     // Find the first different characters in the longwords and
 689     // compute their difference.
 690     bind(DIFFERENCE);
 691     rev(rscratch2, rscratch2);
 692     clz(rscratch2, rscratch2);
 693     andr(rscratch2, rscratch2, isLL ? -8 : -16);
 694     lsrv(tmp1, tmp1, rscratch2);
 695     (this->*ext_chr)(tmp1, tmp1);
 696     lsrv(tmp2, tmp2, rscratch2);
 697     (this->*ext_chr)(tmp2, tmp2);
 698     subw(result, tmp1, tmp2);
 699     b(DONE);
 700   }
 701 
 702   bind(STUB);
 703     RuntimeAddress stub = NULL;
 704     switch(ae) {
 705       case StrIntrinsicNode::LL:
 706         stub = RuntimeAddress(StubRoutines::aarch64::compare_long_string_LL());
 707         break;
 708       case StrIntrinsicNode::UU:
 709         stub = RuntimeAddress(StubRoutines::aarch64::compare_long_string_UU());
 710         break;




 526     sub(cnt1_neg, zr, cnt1, LSL, 1);
 527   BIND(DO1_LOOP);
 528     ldrh(ch1, Address(str1, cnt1_neg));
 529     cmpw(ch, ch1);
 530     br(EQ, MATCH);
 531     adds(cnt1_neg, cnt1_neg, 2);
 532     br(LT, DO1_LOOP);
 533   BIND(NOMATCH);
 534     mov(result, -1);
 535     b(DONE);
 536   BIND(MATCH);
 537     add(result, result_tmp, cnt1_neg, ASR, 1);
 538   BIND(DONE);
 539 }
 540 
 541 // Compare strings.
 542 void C2_MacroAssembler::string_compare(Register str1, Register str2,
 543     Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2,
 544     FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, int ae) {
 545   Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB,
 546       DIFF, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT,
 547       SHORT_LOOP_START, TAIL_CHECK;
 548 
 549   bool isLL = ae == StrIntrinsicNode::LL;
 550   bool isLU = ae == StrIntrinsicNode::LU;
 551   bool isUL = ae == StrIntrinsicNode::UL;
 552 
 553   // The stub threshold for LL strings is: 72 (64 + 8) chars
 554   // UU: 36 chars, or 72 bytes (valid for the 64-byte large loop with prefetch)
 555   // LU/UL: 24 chars, or 48 bytes (valid for the 16-character loop at least)
 556   const u1 stub_threshold = isLL ? 72 : ((isLU || isUL) ? 24 : 36);
 557 
 558   bool str1_isL = isLL || isLU;
 559   bool str2_isL = isLL || isUL;
 560 
 561   int str1_chr_shift = str1_isL ? 0 : 1;
 562   int str2_chr_shift = str2_isL ? 0 : 1;
 563   int str1_chr_size = str1_isL ? 1 : 2;
 564   int str2_chr_size = str2_isL ? 1 : 2;
 565   int minCharsInWord = isLL ? wordSize : wordSize/2;
 566 


 617       add(cnt1, cnt1, 4);
 618       fmovd(tmp1, vtmp);
 619     } else { // UL case
 620       ldr(tmp1, Address(str1));
 621       ldrs(vtmp, Address(str2));
 622       cmp(cnt2, stub_threshold);
 623       br(GE, STUB);
 624       subw(cnt2, cnt2, 4);
 625       lea(str1, Address(str1, cnt2, Address::uxtw(str1_chr_shift)));
 626       eor(vtmpZ, T16B, vtmpZ, vtmpZ);
 627       lea(str2, Address(str2, cnt2, Address::uxtw(str2_chr_shift)));
 628       sub(cnt1, zr, cnt2, LSL, str1_chr_shift);
 629       zip1(vtmp, T8B, vtmp, vtmpZ);
 630       sub(cnt2, zr, cnt2, LSL, str2_chr_shift);
 631       add(cnt1, cnt1, 8);
 632       fmovd(tmp2, vtmp);
 633     }
 634     adds(cnt2, cnt2, isUL ? 4 : 8);
 635     br(GE, TAIL);
 636     eor(rscratch2, tmp1, tmp2);
 637     cbnz(rscratch2, DIFF);
 638     // main loop
 639     bind(NEXT_WORD);
 640     if (str1_isL == str2_isL) {
 641       ldr(tmp1, Address(str1, cnt2));
 642       ldr(tmp2, Address(str2, cnt2));
 643       adds(cnt2, cnt2, 8);
 644     } else if (isLU) {
 645       ldrs(vtmp, Address(str1, cnt1));
 646       ldr(tmp2, Address(str2, cnt2));
 647       add(cnt1, cnt1, 4);
 648       zip1(vtmp, T8B, vtmp, vtmpZ);
 649       fmovd(tmp1, vtmp);
 650       adds(cnt2, cnt2, 8);
 651     } else { // UL
 652       ldrs(vtmp, Address(str2, cnt2));
 653       ldr(tmp1, Address(str1, cnt1));
 654       zip1(vtmp, T8B, vtmp, vtmpZ);
 655       add(cnt1, cnt1, 8);
 656       fmovd(tmp2, vtmp);
 657       adds(cnt2, cnt2, 4);
 658     }
 659     br(GE, TAIL);
 660 
 661     eor(rscratch2, tmp1, tmp2);
 662     cbz(rscratch2, NEXT_WORD);
 663     b(DIFF);
 664     bind(TAIL);
 665     eor(rscratch2, tmp1, tmp2);
 666     cbnz(rscratch2, DIFF);
 667     // Last longword.  In the case where length == 4 we compare the
 668     // same longword twice, but that's still faster than another
 669     // conditional branch.
 670     if (str1_isL == str2_isL) {
 671       ldr(tmp1, Address(str1));
 672       ldr(tmp2, Address(str2));
 673     } else if (isLU) {
 674       ldrs(vtmp, Address(str1));
 675       ldr(tmp2, Address(str2));
 676       zip1(vtmp, T8B, vtmp, vtmpZ);
 677       fmovd(tmp1, vtmp);
 678     } else { // UL
 679       ldrs(vtmp, Address(str2));
 680       ldr(tmp1, Address(str1));
 681       zip1(vtmp, T8B, vtmp, vtmpZ);
 682       fmovd(tmp2, vtmp);
 683     }
 684     bind(TAIL_CHECK);
 685     eor(rscratch2, tmp1, tmp2);
 686     cbz(rscratch2, DONE);
 687 
 688     // Find the first different characters in the longwords and
 689     // compute their difference.
 690     bind(DIFF);
 691     rev(rscratch2, rscratch2);
 692     clz(rscratch2, rscratch2);
 693     andr(rscratch2, rscratch2, isLL ? -8 : -16);
 694     lsrv(tmp1, tmp1, rscratch2);
 695     (this->*ext_chr)(tmp1, tmp1);
 696     lsrv(tmp2, tmp2, rscratch2);
 697     (this->*ext_chr)(tmp2, tmp2);
 698     subw(result, tmp1, tmp2);
 699     b(DONE);
 700   }
 701 
 702   bind(STUB);
 703     RuntimeAddress stub = NULL;
 704     switch(ae) {
 705       case StrIntrinsicNode::LL:
 706         stub = RuntimeAddress(StubRoutines::aarch64::compare_long_string_LL());
 707         break;
 708       case StrIntrinsicNode::UU:
 709         stub = RuntimeAddress(StubRoutines::aarch64::compare_long_string_UU());
 710         break;


< prev index next >