# HG changeset patch # User enevill # Date 1463060203 25200 # Thu May 12 06:36:43 2016 -0700 # Node ID b7af6f55bb1b92bc206db6431d216338916d82b9 # Parent 6e0056d7769d45470a85eb5480d0bbf00d5f5de6 8156839: aarch64: indexOf does not support CompactStrings Summary: Add support for LL to indexOf intrinsic Reviewed-by: aph diff --git a/src/cpu/aarch64/vm/aarch64.ad b/src/cpu/aarch64/vm/aarch64.ad --- a/src/cpu/aarch64/vm/aarch64.ad +++ b/src/cpu/aarch64/vm/aarch64.ad @@ -3331,7 +3331,6 @@ switch (opcode) { case Op_StrComp: - case Op_StrIndexOf: if (CompactStrings) return false; break; default: @@ -14953,7 +14952,7 @@ ins_pipe(pipe_class_memory); %} -instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, +instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); @@ -14967,12 +14966,31 @@ $cnt1$$Register, $cnt2$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, - -1, $result$$Register); + -1, $result$$Register, StrIntrinsicNode::UU); %} ins_pipe(pipe_class_memory); %} -instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, +instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, + iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) +%{ + predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); + match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); + effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, + TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); + format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %} + + ins_encode %{ + __ string_indexof($str1$$Register, $str2$$Register, + $cnt1$$Register, $cnt2$$Register, + $tmp1$$Register, $tmp2$$Register, + $tmp3$$Register, $tmp4$$Register, + -1, $result$$Register, StrIntrinsicNode::LL); + %} + ins_pipe(pipe_class_memory); +%} + +instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) %{ @@ -14988,7 +15006,28 @@ $cnt1$$Register, zr, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, - icnt2, $result$$Register); + icnt2, $result$$Register, StrIntrinsicNode::UU); + %} + ins_pipe(pipe_class_memory); +%} + +instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, + immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, + iRegI tmp3, iRegI tmp4, rFlagsReg cr) +%{ + predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); + match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); + effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, + TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); + format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %} + + ins_encode %{ + int icnt2 = (int)$int_cnt2$$constant; + __ string_indexof($str1$$Register, $str2$$Register, + $cnt1$$Register, zr, + $tmp1$$Register, $tmp2$$Register, + $tmp3$$Register, $tmp4$$Register, + icnt2, $result$$Register, StrIntrinsicNode::LL); %} ins_pipe(pipe_class_memory); %} diff --git a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp --- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp @@ -4136,13 +4136,14 @@ } } +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 icnt1, Register result, int ae) { Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH; Register ch1 = rscratch1; @@ -4153,6 +4154,14 @@ 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; @@ -4242,7 +4251,7 @@ mov(cnt1tmp, 0); sub(cnt1end, cnt1, 1); BIND(BCLOOP); - ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1))); + (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift))); cmp(ch1, 128); add(cnt1tmp, cnt1tmp, 1); br(HS, BCSKIP); @@ -4254,36 +4263,36 @@ mov(result_tmp, str2); sub(cnt2, cnt2, cnt1); - add(str2end, str2, cnt2, LSL, 1); + add(str2end, str2, cnt2, LSL, chr_shift); BIND(BMLOOPSTR2); sub(cnt1tmp, cnt1, 1); - ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1))); - ldrh(skipch, Address(str2, cnt1tmp, Address::lsl(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); - ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1))); - ldrh(ch2, Address(str2, cnt1tmp, Address::lsl(1))); + (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_tmp, str2, result_tmp); - lsr(result, result_tmp, 1); + sub(result, str2, result_tmp); + if (!isL) lsr(result, result, 1); add(sp, sp, 128); b(DONE); BIND(BMADV); - add(str2, str2, 2); + 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, 1); - sub(str2, str2, ch2, LSL, 1); + add(str2, str2, cnt1, LSL, chr_shift); + sub(str2, str2, ch2, LSL, chr_shift); BIND(BMCHECKEND); cmp(str2, str2end); br(LE, BMLOOPSTR2); @@ -4309,39 +4318,39 @@ 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)); + 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); - ldr(ch2, Address(str2, cnt2_neg)); + (this->*load_4chr)(ch2, Address(str2, cnt2_neg)); cmp(first, ch2); br(EQ, STR1_LOOP); BIND(STR2_NEXT); - adds(cnt2_neg, cnt2_neg, 2); + adds(cnt2_neg, cnt2_neg, chr_size); br(LE, FIRST_LOOP); b(NOMATCH); BIND(STR1_LOOP); - adds(cnt1tmp, cnt1_neg, 8); - add(cnt2tmp, cnt2_neg, 8); + adds(cnt1tmp, cnt1_neg, 4*chr_size); + add(cnt2tmp, cnt2_neg, 4*chr_size); br(GE, LAST_WORD); BIND(STR1_NEXT); - ldr(ch1, Address(str1, cnt1tmp)); - ldr(ch2, Address(str2, cnt2tmp)); + (this->*load_4chr)(ch1, Address(str1, cnt1tmp)); + (this->*load_4chr)(ch2, Address(str2, cnt2tmp)); cmp(ch1, ch2); br(NE, STR2_NEXT); - adds(cnt1tmp, cnt1tmp, 8); - add(cnt2tmp, cnt2tmp, 8); + adds(cnt1tmp, cnt1tmp, 4*chr_size); + add(cnt2tmp, cnt2tmp, 4*chr_size); br(LT, STR1_NEXT); BIND(LAST_WORD); - ldr(ch1, Address(str1)); + (this->*load_4chr)(ch1, Address(str1)); sub(str2tmp, str2, cnt1_neg); // adjust to corresponding - ldr(ch2, Address(str2tmp, cnt2_neg)); // word in str2 + (this->*load_4chr)(ch2, Address(str2tmp, cnt2_neg)); // word in str2 cmp(ch1, ch2); br(NE, STR2_NEXT); b(MATCH); @@ -4355,17 +4364,17 @@ if (icnt1 == 4) { Label CH1_LOOP; - ldr(ch1, str1); + (this->*load_4chr)(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); + lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); + sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(CH1_LOOP); - ldr(ch2, Address(str2, cnt2_neg)); + (this->*load_4chr)(ch2, Address(str2, cnt2_neg)); cmp(ch1, ch2); br(EQ, MATCH); - adds(cnt2_neg, cnt2_neg, 2); + adds(cnt2_neg, cnt2_neg, chr_size); br(LE, CH1_LOOP); b(NOMATCH); } @@ -4374,17 +4383,17 @@ Label CH1_LOOP; BIND(DO2); - ldrw(ch1, str1); + (this->*load_2chr)(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); + lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); + sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(CH1_LOOP); - ldrw(ch2, Address(str2, cnt2_neg)); + (this->*load_2chr)(ch2, Address(str2, cnt2_neg)); cmp(ch1, ch2); br(EQ, MATCH); - adds(cnt2_neg, cnt2_neg, 2); + adds(cnt2_neg, cnt2_neg, chr_size); br(LE, CH1_LOOP); b(NOMATCH); } @@ -4393,26 +4402,26 @@ Label FIRST_LOOP, STR2_NEXT, STR1_LOOP; BIND(DO3); - ldrw(first, str1); - ldrh(ch1, Address(str1, 4)); + (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::uxtw(1))); - sub(cnt2_neg, zr, cnt2, LSL, 1); + lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); + sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(FIRST_LOOP); - ldrw(ch2, Address(str2, cnt2_neg)); + (this->*load_2chr)(ch2, Address(str2, cnt2_neg)); cmpw(first, ch2); br(EQ, STR1_LOOP); BIND(STR2_NEXT); - adds(cnt2_neg, cnt2_neg, 2); + adds(cnt2_neg, cnt2_neg, chr_size); br(LE, FIRST_LOOP); b(NOMATCH); BIND(STR1_LOOP); - add(cnt2tmp, cnt2_neg, 4); - ldrh(ch2, Address(str2, cnt2tmp)); + add(cnt2tmp, cnt2_neg, 2*chr_size); + (this->*load_chr)(ch2, Address(str2, cnt2tmp)); cmp(ch1, ch2); br(NE, STR2_NEXT); b(MATCH); @@ -4423,24 +4432,25 @@ Label DO1_SHORT, DO1_LOOP; BIND(DO1); - ldrh(ch1, str1); - cmp(cnt2, 4); + (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, 4); + sub(cnt2, cnt2, 8/chr_size); mov(result_tmp, cnt2); - lea(str2, Address(str2, cnt2, Address::uxtw(1))); - sub(cnt2_neg, zr, cnt2, LSL, 1); - - mov(tmp3, 0x0001000100010001); + 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, 0x7fff7fff7fff7fff); + orr(tmp2, ch2, isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff); bics(tmp1, tmp1, tmp2); br(NE, HAS_ZERO); adds(cnt2_neg, cnt2_neg, 8); @@ -4459,13 +4469,13 @@ BIND(DO1_SHORT); mov(result_tmp, cnt2); - lea(str2, Address(str2, cnt2, Address::uxtw(1))); - sub(cnt2_neg, zr, cnt2, LSL, 1); + lea(str2, Address(str2, cnt2, Address::lsl(chr_shift))); + sub(cnt2_neg, zr, cnt2, LSL, chr_shift); BIND(DO1_LOOP); - ldrh(ch2, Address(str2, cnt2_neg)); + (this->*load_chr)(ch2, Address(str2, cnt2_neg)); cmpw(ch1, ch2); br(EQ, MATCH); - adds(cnt2_neg, cnt2_neg, 2); + adds(cnt2_neg, cnt2_neg, chr_size); br(LT, DO1_LOOP); } } @@ -4473,7 +4483,7 @@ mov(result, -1); b(DONE); BIND(MATCH); - add(result, result_tmp, cnt2_neg, ASR, 1); + add(result, result_tmp, cnt2_neg, ASR, chr_shift); BIND(DONE); } diff --git a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp --- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp +++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp @@ -1217,7 +1217,7 @@ Register cnt1, Register cnt2, Register tmp1, Register tmp2, Register tmp3, Register tmp4, - int int_cnt1, Register result); + int int_cnt1, Register result, int ae); private: void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo, Register src1, Register src2);