< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.cpp

Print this page
rev 11229 : 8156839: aarch64: indexOf does not support CompactStrings
Summary: Add support for LL to indexOf intrinsic
Reviewed-by: aph

*** 4134,4160 **** } ldp(rfp, lr, Address(post(sp, 2 * wordSize))); } } // Search for str1 in str2 and return index or -1 void MacroAssembler::string_indexof(Register str2, Register str1, Register cnt2, Register cnt1, Register tmp1, Register tmp2, Register tmp3, Register tmp4, ! int icnt1, Register result) { Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH; Register ch1 = rscratch1; Register ch2 = rscratch2; Register cnt1tmp = tmp1; Register cnt2tmp = tmp2; Register cnt1_neg = cnt1; Register cnt2_neg = cnt2; Register result_tmp = tmp4; // Note, inline_string_indexOf() generates checks: // if (substr.count > string.count) return -1; // if (substr.count == 0) return 0; // We have two strings, a source string in str2, cnt2 and a pattern string --- 4134,4169 ---- } ldp(rfp, lr, Address(post(sp, 2 * wordSize))); } } + typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr); // Search for str1 in str2 and return index or -1 void MacroAssembler::string_indexof(Register str2, Register str1, Register cnt2, Register cnt1, Register tmp1, Register tmp2, Register tmp3, Register tmp4, ! int icnt1, Register result, int ae) { Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH; Register ch1 = rscratch1; Register ch2 = rscratch2; Register cnt1tmp = tmp1; Register cnt2tmp = tmp2; Register cnt1_neg = cnt1; Register cnt2_neg = cnt2; Register result_tmp = tmp4; + guarantee(ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU, "unhandled argument encoding"); + bool isL = ae == StrIntrinsicNode::LL; + int chr_shift = isL ? 0:1; + int chr_size = isL ? 1:2; + chr_insn load_chr = isL ? (chr_insn)&MacroAssembler::ldrb : (chr_insn)&MacroAssembler::ldrh; + chr_insn load_2chr = isL ? (chr_insn)&MacroAssembler::ldrh : (chr_insn)&MacroAssembler::ldrw; + chr_insn load_4chr = isL ? (chr_insn)&MacroAssembler::ldrw : (chr_insn)&MacroAssembler::ldr; + // Note, inline_string_indexOf() generates checks: // if (substr.count > string.count) return -1; // if (substr.count == 0) return 0; // We have two strings, a source string in str2, cnt2 and a pattern string
*** 4240,4250 **** stp(zr, zr, Address(sp, i*16)); mov(cnt1tmp, 0); sub(cnt1end, cnt1, 1); BIND(BCLOOP); ! ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1))); cmp(ch1, 128); add(cnt1tmp, cnt1tmp, 1); br(HS, BCSKIP); strb(cnt1tmp, Address(sp, ch1)); BIND(BCSKIP); --- 4249,4259 ---- stp(zr, zr, Address(sp, i*16)); mov(cnt1tmp, 0); sub(cnt1end, cnt1, 1); BIND(BCLOOP); ! (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift))); cmp(ch1, 128); add(cnt1tmp, cnt1tmp, 1); br(HS, BCSKIP); strb(cnt1tmp, Address(sp, ch1)); BIND(BCSKIP);
*** 4252,4291 **** br(LT, BCLOOP); mov(result_tmp, str2); sub(cnt2, cnt2, cnt1); ! add(str2end, str2, cnt2, LSL, 1); BIND(BMLOOPSTR2); sub(cnt1tmp, cnt1, 1); ! ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1))); ! ldrh(skipch, Address(str2, cnt1tmp, Address::lsl(1))); cmp(ch1, skipch); br(NE, BMSKIP); subs(cnt1tmp, cnt1tmp, 1); br(LT, BMMATCH); BIND(BMLOOPSTR1); ! ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1))); ! ldrh(ch2, Address(str2, cnt1tmp, Address::lsl(1))); cmp(ch1, ch2); br(NE, BMSKIP); subs(cnt1tmp, cnt1tmp, 1); br(GE, BMLOOPSTR1); BIND(BMMATCH); ! sub(result_tmp, str2, result_tmp); ! lsr(result, result_tmp, 1); add(sp, sp, 128); b(DONE); BIND(BMADV); ! add(str2, str2, 2); b(BMCHECKEND); BIND(BMSKIP); cmp(skipch, 128); br(HS, BMADV); ldrb(ch2, Address(sp, skipch)); ! add(str2, str2, cnt1, LSL, 1); ! sub(str2, str2, ch2, LSL, 1); BIND(BMCHECKEND); cmp(str2, str2end); br(LE, BMLOOPSTR2); add(sp, sp, 128); b(NOMATCH); --- 4261,4300 ---- br(LT, BCLOOP); mov(result_tmp, str2); sub(cnt2, cnt2, cnt1); ! add(str2end, str2, cnt2, LSL, chr_shift); BIND(BMLOOPSTR2); sub(cnt1tmp, cnt1, 1); ! (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift))); ! (this->*load_chr)(skipch, Address(str2, cnt1tmp, Address::lsl(chr_shift))); cmp(ch1, skipch); br(NE, BMSKIP); subs(cnt1tmp, cnt1tmp, 1); br(LT, BMMATCH); BIND(BMLOOPSTR1); ! (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift))); ! (this->*load_chr)(ch2, Address(str2, cnt1tmp, Address::lsl(chr_shift))); cmp(ch1, ch2); br(NE, BMSKIP); subs(cnt1tmp, cnt1tmp, 1); br(GE, BMLOOPSTR1); BIND(BMMATCH); ! sub(result, str2, result_tmp); ! if (!isL) lsr(result, result, 1); add(sp, sp, 128); b(DONE); BIND(BMADV); ! add(str2, str2, chr_size); b(BMCHECKEND); BIND(BMSKIP); cmp(skipch, 128); br(HS, BMADV); ldrb(ch2, Address(sp, skipch)); ! add(str2, str2, cnt1, LSL, chr_shift); ! sub(str2, str2, ch2, LSL, chr_shift); BIND(BMCHECKEND); cmp(str2, str2end); br(LE, BMLOOPSTR2); add(sp, sp, 128); b(NOMATCH);
*** 4307,4349 **** sub(cnt2, cnt2, cnt1); sub(cnt1, cnt1, 4); mov(result_tmp, cnt2); ! lea(str1, Address(str1, cnt1, Address::uxtw(1))); ! lea(str2, Address(str2, cnt2, Address::uxtw(1))); ! sub(cnt1_neg, zr, cnt1, LSL, 1); ! sub(cnt2_neg, zr, cnt2, LSL, 1); ! ldr(first, Address(str1, cnt1_neg)); BIND(FIRST_LOOP); ! ldr(ch2, Address(str2, cnt2_neg)); cmp(first, ch2); br(EQ, STR1_LOOP); BIND(STR2_NEXT); ! adds(cnt2_neg, cnt2_neg, 2); br(LE, FIRST_LOOP); b(NOMATCH); BIND(STR1_LOOP); ! adds(cnt1tmp, cnt1_neg, 8); ! add(cnt2tmp, cnt2_neg, 8); br(GE, LAST_WORD); BIND(STR1_NEXT); ! ldr(ch1, Address(str1, cnt1tmp)); ! ldr(ch2, Address(str2, cnt2tmp)); cmp(ch1, ch2); br(NE, STR2_NEXT); ! adds(cnt1tmp, cnt1tmp, 8); ! add(cnt2tmp, cnt2tmp, 8); br(LT, STR1_NEXT); BIND(LAST_WORD); ! ldr(ch1, Address(str1)); sub(str2tmp, str2, cnt1_neg); // adjust to corresponding ! ldr(ch2, Address(str2tmp, cnt2_neg)); // word in str2 cmp(ch1, ch2); br(NE, STR2_NEXT); b(MATCH); BIND(DOSHORT); --- 4316,4358 ---- sub(cnt2, cnt2, cnt1); sub(cnt1, cnt1, 4); mov(result_tmp, cnt2); ! lea(str1, Address(str1, cnt1, Address::lsl(chr_shift))); ! lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); ! sub(cnt1_neg, zr, cnt1, LSL, chr_shift); ! sub(cnt2_neg, zr, cnt2, LSL, chr_shift); ! (this->*load_4chr)(first, Address(str1, cnt1_neg)); BIND(FIRST_LOOP); ! (this->*load_4chr)(ch2, Address(str2, cnt2_neg)); cmp(first, ch2); br(EQ, STR1_LOOP); BIND(STR2_NEXT); ! adds(cnt2_neg, cnt2_neg, chr_size); br(LE, FIRST_LOOP); b(NOMATCH); BIND(STR1_LOOP); ! adds(cnt1tmp, cnt1_neg, 4*chr_size); ! add(cnt2tmp, cnt2_neg, 4*chr_size); br(GE, LAST_WORD); BIND(STR1_NEXT); ! (this->*load_4chr)(ch1, Address(str1, cnt1tmp)); ! (this->*load_4chr)(ch2, Address(str2, cnt2tmp)); cmp(ch1, ch2); br(NE, STR2_NEXT); ! adds(cnt1tmp, cnt1tmp, 4*chr_size); ! add(cnt2tmp, cnt2tmp, 4*chr_size); br(LT, STR1_NEXT); BIND(LAST_WORD); ! (this->*load_4chr)(ch1, Address(str1)); sub(str2tmp, str2, cnt1_neg); // adjust to corresponding ! (this->*load_4chr)(ch2, Address(str2tmp, cnt2_neg)); // word in str2 cmp(ch1, ch2); br(NE, STR2_NEXT); b(MATCH); BIND(DOSHORT);
*** 4353,4448 **** } if (icnt1 == 4) { Label CH1_LOOP; ! ldr(ch1, str1); sub(cnt2, cnt2, 4); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::uxtw(1))); ! sub(cnt2_neg, zr, cnt2, LSL, 1); BIND(CH1_LOOP); ! ldr(ch2, Address(str2, cnt2_neg)); cmp(ch1, ch2); br(EQ, MATCH); ! adds(cnt2_neg, cnt2_neg, 2); br(LE, CH1_LOOP); b(NOMATCH); } if (icnt1 == -1 || icnt1 == 2) { Label CH1_LOOP; BIND(DO2); ! ldrw(ch1, str1); sub(cnt2, cnt2, 2); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::uxtw(1))); ! sub(cnt2_neg, zr, cnt2, LSL, 1); BIND(CH1_LOOP); ! ldrw(ch2, Address(str2, cnt2_neg)); cmp(ch1, ch2); br(EQ, MATCH); ! adds(cnt2_neg, cnt2_neg, 2); br(LE, CH1_LOOP); b(NOMATCH); } if (icnt1 == -1 || icnt1 == 3) { Label FIRST_LOOP, STR2_NEXT, STR1_LOOP; BIND(DO3); ! ldrw(first, str1); ! ldrh(ch1, Address(str1, 4)); sub(cnt2, cnt2, 3); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::uxtw(1))); ! sub(cnt2_neg, zr, cnt2, LSL, 1); BIND(FIRST_LOOP); ! ldrw(ch2, Address(str2, cnt2_neg)); cmpw(first, ch2); br(EQ, STR1_LOOP); BIND(STR2_NEXT); ! adds(cnt2_neg, cnt2_neg, 2); br(LE, FIRST_LOOP); b(NOMATCH); BIND(STR1_LOOP); ! add(cnt2tmp, cnt2_neg, 4); ! ldrh(ch2, Address(str2, cnt2tmp)); cmp(ch1, ch2); br(NE, STR2_NEXT); b(MATCH); } if (icnt1 == -1 || icnt1 == 1) { Label CH1_LOOP, HAS_ZERO; Label DO1_SHORT, DO1_LOOP; BIND(DO1); ! ldrh(ch1, str1); ! cmp(cnt2, 4); br(LT, DO1_SHORT); orr(ch1, ch1, ch1, LSL, 16); orr(ch1, ch1, ch1, LSL, 32); ! sub(cnt2, cnt2, 4); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::uxtw(1))); ! sub(cnt2_neg, zr, cnt2, LSL, 1); ! mov(tmp3, 0x0001000100010001); BIND(CH1_LOOP); ldr(ch2, Address(str2, cnt2_neg)); eor(ch2, ch1, ch2); sub(tmp1, ch2, tmp3); ! orr(tmp2, ch2, 0x7fff7fff7fff7fff); bics(tmp1, tmp1, tmp2); br(NE, HAS_ZERO); adds(cnt2_neg, cnt2_neg, 8); br(LT, CH1_LOOP); --- 4362,4458 ---- } if (icnt1 == 4) { Label CH1_LOOP; ! (this->*load_4chr)(ch1, str1); sub(cnt2, cnt2, 4); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); ! sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(CH1_LOOP); ! (this->*load_4chr)(ch2, Address(str2, cnt2_neg)); cmp(ch1, ch2); br(EQ, MATCH); ! adds(cnt2_neg, cnt2_neg, chr_size); br(LE, CH1_LOOP); b(NOMATCH); } if (icnt1 == -1 || icnt1 == 2) { Label CH1_LOOP; BIND(DO2); ! (this->*load_2chr)(ch1, str1); sub(cnt2, cnt2, 2); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); ! sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(CH1_LOOP); ! (this->*load_2chr)(ch2, Address(str2, cnt2_neg)); cmp(ch1, ch2); br(EQ, MATCH); ! adds(cnt2_neg, cnt2_neg, chr_size); br(LE, CH1_LOOP); b(NOMATCH); } if (icnt1 == -1 || icnt1 == 3) { Label FIRST_LOOP, STR2_NEXT, STR1_LOOP; BIND(DO3); ! (this->*load_2chr)(first, str1); ! (this->*load_chr)(ch1, Address(str1, 2*chr_size)); sub(cnt2, cnt2, 3); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); ! sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(FIRST_LOOP); ! (this->*load_2chr)(ch2, Address(str2, cnt2_neg)); cmpw(first, ch2); br(EQ, STR1_LOOP); BIND(STR2_NEXT); ! adds(cnt2_neg, cnt2_neg, chr_size); br(LE, FIRST_LOOP); b(NOMATCH); BIND(STR1_LOOP); ! add(cnt2tmp, cnt2_neg, 2*chr_size); ! (this->*load_chr)(ch2, Address(str2, cnt2tmp)); cmp(ch1, ch2); br(NE, STR2_NEXT); b(MATCH); } if (icnt1 == -1 || icnt1 == 1) { Label CH1_LOOP, HAS_ZERO; Label DO1_SHORT, DO1_LOOP; BIND(DO1); ! (this->*load_chr)(ch1, str1); ! cmp(cnt2, 8); br(LT, DO1_SHORT); + if (isL) orr(ch1, ch1, ch1, LSL, 8); orr(ch1, ch1, ch1, LSL, 16); orr(ch1, ch1, ch1, LSL, 32); ! sub(cnt2, cnt2, 8/chr_size); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); ! sub(cnt2_neg, zr, cnt2, LSL, chr_shift); ! mov(tmp3, isL ? 0x0101010101010101 : 0x0001000100010001); BIND(CH1_LOOP); ldr(ch2, Address(str2, cnt2_neg)); eor(ch2, ch1, ch2); sub(tmp1, ch2, tmp3); ! orr(tmp2, ch2, isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff); bics(tmp1, tmp1, tmp2); br(NE, HAS_ZERO); adds(cnt2_neg, cnt2_neg, 8); br(LT, CH1_LOOP);
*** 4457,4481 **** add(cnt2_neg, cnt2_neg, tmp1, LSR, 3); b(MATCH); BIND(DO1_SHORT); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::uxtw(1))); ! sub(cnt2_neg, zr, cnt2, LSL, 1); BIND(DO1_LOOP); ! ldrh(ch2, Address(str2, cnt2_neg)); cmpw(ch1, ch2); br(EQ, MATCH); ! adds(cnt2_neg, cnt2_neg, 2); br(LT, DO1_LOOP); } } BIND(NOMATCH); mov(result, -1); b(DONE); BIND(MATCH); ! add(result, result_tmp, cnt2_neg, ASR, 1); BIND(DONE); } // Compare strings. void MacroAssembler::string_compare(Register str1, Register str2, --- 4467,4491 ---- add(cnt2_neg, cnt2_neg, tmp1, LSR, 3); b(MATCH); BIND(DO1_SHORT); mov(result_tmp, cnt2); ! lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); ! sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(DO1_LOOP); ! (this->*load_chr)(ch2, Address(str2, cnt2_neg)); cmpw(ch1, ch2); br(EQ, MATCH); ! adds(cnt2_neg, cnt2_neg, chr_size); br(LT, DO1_LOOP); } } BIND(NOMATCH); mov(result, -1); b(DONE); BIND(MATCH); ! add(result, result_tmp, cnt2_neg, ASR, chr_shift); BIND(DONE); } // Compare strings. void MacroAssembler::string_compare(Register str1, Register str2,
< prev index next >