< 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 >