8157834: aarch64: Hello World crashes with fastdebug build
Support LL, UL and LU encodings of StrIndexOf Reviewed-by: aph
This commit is contained in:
parent
ac5718b306
commit
7694596568
@ -3331,7 +3331,6 @@ const bool Matcher::match_rule_supported(int opcode) {
|
|||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Op_StrComp:
|
case Op_StrComp:
|
||||||
case Op_StrIndexOf:
|
|
||||||
if (CompactStrings) return false;
|
if (CompactStrings) return false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -14953,26 +14952,83 @@ instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 c
|
|||||||
ins_pipe(pipe_class_memory);
|
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)
|
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
|
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
|
||||||
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
|
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||||
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
|
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
|
||||||
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
|
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
|
||||||
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %}
|
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
|
||||||
|
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ string_indexof($str1$$Register, $str2$$Register,
|
__ string_indexof($str1$$Register, $str2$$Register,
|
||||||
$cnt1$$Register, $cnt2$$Register,
|
$cnt1$$Register, $cnt2$$Register,
|
||||||
$tmp1$$Register, $tmp2$$Register,
|
$tmp1$$Register, $tmp2$$Register,
|
||||||
$tmp3$$Register, $tmp4$$Register,
|
$tmp3$$Register, $tmp4$$Register,
|
||||||
-1, $result$$Register);
|
-1, $result$$Register, StrIntrinsicNode::UU);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_memory);
|
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 (LL)" %}
|
||||||
|
|
||||||
|
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_indexofUL(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::UL);
|
||||||
|
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 (UL)" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ string_indexof($str1$$Register, $str2$$Register,
|
||||||
|
$cnt1$$Register, $cnt2$$Register,
|
||||||
|
$tmp1$$Register, $tmp2$$Register,
|
||||||
|
$tmp3$$Register, $tmp4$$Register,
|
||||||
|
-1, $result$$Register, StrIntrinsicNode::UL);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_memory);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct string_indexofLU(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::LU);
|
||||||
|
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 (LU)" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ string_indexof($str1$$Register, $str2$$Register,
|
||||||
|
$cnt1$$Register, $cnt2$$Register,
|
||||||
|
$tmp1$$Register, $tmp2$$Register,
|
||||||
|
$tmp3$$Register, $tmp4$$Register,
|
||||||
|
-1, $result$$Register, StrIntrinsicNode::LU);
|
||||||
|
%}
|
||||||
|
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,
|
immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
|
||||||
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
@ -14980,7 +15036,7 @@ instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
|
|||||||
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
|
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
|
||||||
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
|
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
|
||||||
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
|
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
|
||||||
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %}
|
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %}
|
||||||
|
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int icnt2 = (int)$int_cnt2$$constant;
|
int icnt2 = (int)$int_cnt2$$constant;
|
||||||
@ -14988,7 +15044,70 @@ instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
|
|||||||
$cnt1$$Register, zr,
|
$cnt1$$Register, zr,
|
||||||
$tmp1$$Register, $tmp2$$Register,
|
$tmp1$$Register, $tmp2$$Register,
|
||||||
$tmp3$$Register, $tmp4$$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 (LL)" %}
|
||||||
|
|
||||||
|
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);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
|
||||||
|
immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
|
||||||
|
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
|
||||||
|
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 (UL)" %}
|
||||||
|
|
||||||
|
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::UL);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_memory);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct string_indexof_conLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
|
||||||
|
immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
|
||||||
|
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
|
||||||
|
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 (LU)" %}
|
||||||
|
|
||||||
|
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::LU);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_memory);
|
ins_pipe(pipe_class_memory);
|
||||||
%}
|
%}
|
||||||
|
@ -4136,13 +4136,14 @@ void MacroAssembler::remove_frame(int framesize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
|
||||||
|
|
||||||
// Search for str1 in str2 and return index or -1
|
// Search for str1 in str2 and return index or -1
|
||||||
void MacroAssembler::string_indexof(Register str2, Register str1,
|
void MacroAssembler::string_indexof(Register str2, Register str1,
|
||||||
Register cnt2, Register cnt1,
|
Register cnt2, Register cnt1,
|
||||||
Register tmp1, Register tmp2,
|
Register tmp1, Register tmp2,
|
||||||
Register tmp3, Register tmp4,
|
Register tmp3, Register tmp4,
|
||||||
int icnt1, Register result) {
|
int icnt1, Register result, int ae) {
|
||||||
Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
|
Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
|
||||||
|
|
||||||
Register ch1 = rscratch1;
|
Register ch1 = rscratch1;
|
||||||
@ -4153,6 +4154,21 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
Register cnt2_neg = cnt2;
|
Register cnt2_neg = cnt2;
|
||||||
Register result_tmp = tmp4;
|
Register result_tmp = tmp4;
|
||||||
|
|
||||||
|
bool isL = ae == StrIntrinsicNode::LL;
|
||||||
|
|
||||||
|
bool str1_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UL;
|
||||||
|
bool str2_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::LU;
|
||||||
|
int str1_chr_shift = str1_isL ? 0:1;
|
||||||
|
int str2_chr_shift = str2_isL ? 0:1;
|
||||||
|
int str1_chr_size = str1_isL ? 1:2;
|
||||||
|
int str2_chr_size = str2_isL ? 1:2;
|
||||||
|
chr_insn str1_load_1chr = str1_isL ? (chr_insn)&MacroAssembler::ldrb :
|
||||||
|
(chr_insn)&MacroAssembler::ldrh;
|
||||||
|
chr_insn str2_load_1chr = str2_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:
|
// Note, inline_string_indexOf() generates checks:
|
||||||
// if (substr.count > string.count) return -1;
|
// if (substr.count > string.count) return -1;
|
||||||
// if (substr.count == 0) return 0;
|
// if (substr.count == 0) return 0;
|
||||||
@ -4242,7 +4258,7 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
mov(cnt1tmp, 0);
|
mov(cnt1tmp, 0);
|
||||||
sub(cnt1end, cnt1, 1);
|
sub(cnt1end, cnt1, 1);
|
||||||
BIND(BCLOOP);
|
BIND(BCLOOP);
|
||||||
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
|
||||||
cmp(ch1, 128);
|
cmp(ch1, 128);
|
||||||
add(cnt1tmp, cnt1tmp, 1);
|
add(cnt1tmp, cnt1tmp, 1);
|
||||||
br(HS, BCSKIP);
|
br(HS, BCSKIP);
|
||||||
@ -4254,36 +4270,36 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
mov(result_tmp, str2);
|
mov(result_tmp, str2);
|
||||||
|
|
||||||
sub(cnt2, cnt2, cnt1);
|
sub(cnt2, cnt2, cnt1);
|
||||||
add(str2end, str2, cnt2, LSL, 1);
|
add(str2end, str2, cnt2, LSL, str2_chr_shift);
|
||||||
BIND(BMLOOPSTR2);
|
BIND(BMLOOPSTR2);
|
||||||
sub(cnt1tmp, cnt1, 1);
|
sub(cnt1tmp, cnt1, 1);
|
||||||
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
|
||||||
ldrh(skipch, Address(str2, cnt1tmp, Address::lsl(1)));
|
(this->*str2_load_1chr)(skipch, Address(str2, cnt1tmp, Address::lsl(str2_chr_shift)));
|
||||||
cmp(ch1, skipch);
|
cmp(ch1, skipch);
|
||||||
br(NE, BMSKIP);
|
br(NE, BMSKIP);
|
||||||
subs(cnt1tmp, cnt1tmp, 1);
|
subs(cnt1tmp, cnt1tmp, 1);
|
||||||
br(LT, BMMATCH);
|
br(LT, BMMATCH);
|
||||||
BIND(BMLOOPSTR1);
|
BIND(BMLOOPSTR1);
|
||||||
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
|
||||||
ldrh(ch2, Address(str2, cnt1tmp, Address::lsl(1)));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt1tmp, Address::lsl(str2_chr_shift)));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(NE, BMSKIP);
|
br(NE, BMSKIP);
|
||||||
subs(cnt1tmp, cnt1tmp, 1);
|
subs(cnt1tmp, cnt1tmp, 1);
|
||||||
br(GE, BMLOOPSTR1);
|
br(GE, BMLOOPSTR1);
|
||||||
BIND(BMMATCH);
|
BIND(BMMATCH);
|
||||||
sub(result_tmp, str2, result_tmp);
|
sub(result, str2, result_tmp);
|
||||||
lsr(result, result_tmp, 1);
|
if (!str2_isL) lsr(result, result, 1);
|
||||||
add(sp, sp, 128);
|
add(sp, sp, 128);
|
||||||
b(DONE);
|
b(DONE);
|
||||||
BIND(BMADV);
|
BIND(BMADV);
|
||||||
add(str2, str2, 2);
|
add(str2, str2, str2_chr_size);
|
||||||
b(BMCHECKEND);
|
b(BMCHECKEND);
|
||||||
BIND(BMSKIP);
|
BIND(BMSKIP);
|
||||||
cmp(skipch, 128);
|
cmp(skipch, 128);
|
||||||
br(HS, BMADV);
|
br(HS, BMADV);
|
||||||
ldrb(ch2, Address(sp, skipch));
|
ldrb(ch2, Address(sp, skipch));
|
||||||
add(str2, str2, cnt1, LSL, 1);
|
add(str2, str2, cnt1, LSL, str2_chr_shift);
|
||||||
sub(str2, str2, ch2, LSL, 1);
|
sub(str2, str2, ch2, LSL, str2_chr_shift);
|
||||||
BIND(BMCHECKEND);
|
BIND(BMCHECKEND);
|
||||||
cmp(str2, str2end);
|
cmp(str2, str2end);
|
||||||
br(LE, BMLOOPSTR2);
|
br(LE, BMLOOPSTR2);
|
||||||
@ -4300,119 +4316,113 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
|
|
||||||
if (icnt1 == -1)
|
if (icnt1 == -1)
|
||||||
{
|
{
|
||||||
Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT, LAST_WORD;
|
Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT;
|
||||||
|
|
||||||
cmp(cnt1, 4);
|
cmp(cnt1, str1_isL == str2_isL ? 4 : 2);
|
||||||
br(LT, DOSHORT);
|
br(LT, DOSHORT);
|
||||||
|
|
||||||
sub(cnt2, cnt2, cnt1);
|
sub(cnt2, cnt2, cnt1);
|
||||||
sub(cnt1, cnt1, 4);
|
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
|
|
||||||
lea(str1, Address(str1, cnt1, Address::uxtw(1)));
|
lea(str1, Address(str1, cnt1, Address::lsl(str1_chr_shift)));
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt1_neg, zr, cnt1, LSL, 1);
|
sub(cnt1_neg, zr, cnt1, LSL, str1_chr_shift);
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
ldr(first, Address(str1, cnt1_neg));
|
(this->*str1_load_1chr)(first, Address(str1, cnt1_neg));
|
||||||
|
|
||||||
BIND(FIRST_LOOP);
|
BIND(FIRST_LOOP);
|
||||||
ldr(ch2, Address(str2, cnt2_neg));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmp(first, ch2);
|
cmp(first, ch2);
|
||||||
br(EQ, STR1_LOOP);
|
br(EQ, STR1_LOOP);
|
||||||
BIND(STR2_NEXT);
|
BIND(STR2_NEXT);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, FIRST_LOOP);
|
br(LE, FIRST_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
|
|
||||||
BIND(STR1_LOOP);
|
BIND(STR1_LOOP);
|
||||||
adds(cnt1tmp, cnt1_neg, 8);
|
adds(cnt1tmp, cnt1_neg, str1_chr_size);
|
||||||
add(cnt2tmp, cnt2_neg, 8);
|
add(cnt2tmp, cnt2_neg, str2_chr_size);
|
||||||
br(GE, LAST_WORD);
|
br(GE, MATCH);
|
||||||
|
|
||||||
BIND(STR1_NEXT);
|
BIND(STR1_NEXT);
|
||||||
ldr(ch1, Address(str1, cnt1tmp));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp));
|
||||||
ldr(ch2, Address(str2, cnt2tmp));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(NE, STR2_NEXT);
|
br(NE, STR2_NEXT);
|
||||||
adds(cnt1tmp, cnt1tmp, 8);
|
adds(cnt1tmp, cnt1tmp, str1_chr_size);
|
||||||
add(cnt2tmp, cnt2tmp, 8);
|
add(cnt2tmp, cnt2tmp, str2_chr_size);
|
||||||
br(LT, STR1_NEXT);
|
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);
|
b(MATCH);
|
||||||
|
|
||||||
BIND(DOSHORT);
|
BIND(DOSHORT);
|
||||||
|
if (str1_isL == str2_isL) {
|
||||||
cmp(cnt1, 2);
|
cmp(cnt1, 2);
|
||||||
br(LT, DO1);
|
br(LT, DO1);
|
||||||
br(GT, DO3);
|
br(GT, DO3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icnt1 == 4) {
|
if (icnt1 == 4) {
|
||||||
Label CH1_LOOP;
|
Label CH1_LOOP;
|
||||||
|
|
||||||
ldr(ch1, str1);
|
(this->*load_4chr)(ch1, str1);
|
||||||
sub(cnt2, cnt2, 4);
|
sub(cnt2, cnt2, 4);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
BIND(CH1_LOOP);
|
BIND(CH1_LOOP);
|
||||||
ldr(ch2, Address(str2, cnt2_neg));
|
(this->*load_4chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(EQ, MATCH);
|
br(EQ, MATCH);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, CH1_LOOP);
|
br(LE, CH1_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icnt1 == -1 || icnt1 == 2) {
|
if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 2) {
|
||||||
Label CH1_LOOP;
|
Label CH1_LOOP;
|
||||||
|
|
||||||
BIND(DO2);
|
BIND(DO2);
|
||||||
ldrw(ch1, str1);
|
(this->*load_2chr)(ch1, str1);
|
||||||
sub(cnt2, cnt2, 2);
|
sub(cnt2, cnt2, 2);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
BIND(CH1_LOOP);
|
BIND(CH1_LOOP);
|
||||||
ldrw(ch2, Address(str2, cnt2_neg));
|
(this->*load_2chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(EQ, MATCH);
|
br(EQ, MATCH);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, CH1_LOOP);
|
br(LE, CH1_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icnt1 == -1 || icnt1 == 3) {
|
if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 3) {
|
||||||
Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
|
Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
|
||||||
|
|
||||||
BIND(DO3);
|
BIND(DO3);
|
||||||
ldrw(first, str1);
|
(this->*load_2chr)(first, str1);
|
||||||
ldrh(ch1, Address(str1, 4));
|
(this->*str1_load_1chr)(ch1, Address(str1, 2*str1_chr_size));
|
||||||
|
|
||||||
sub(cnt2, cnt2, 3);
|
sub(cnt2, cnt2, 3);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
BIND(FIRST_LOOP);
|
BIND(FIRST_LOOP);
|
||||||
ldrw(ch2, Address(str2, cnt2_neg));
|
(this->*load_2chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmpw(first, ch2);
|
cmpw(first, ch2);
|
||||||
br(EQ, STR1_LOOP);
|
br(EQ, STR1_LOOP);
|
||||||
BIND(STR2_NEXT);
|
BIND(STR2_NEXT);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, FIRST_LOOP);
|
br(LE, FIRST_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
|
|
||||||
BIND(STR1_LOOP);
|
BIND(STR1_LOOP);
|
||||||
add(cnt2tmp, cnt2_neg, 4);
|
add(cnt2tmp, cnt2_neg, 2*str2_chr_size);
|
||||||
ldrh(ch2, Address(str2, cnt2tmp));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(NE, STR2_NEXT);
|
br(NE, STR2_NEXT);
|
||||||
b(MATCH);
|
b(MATCH);
|
||||||
@ -4423,24 +4433,31 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
Label DO1_SHORT, DO1_LOOP;
|
Label DO1_SHORT, DO1_LOOP;
|
||||||
|
|
||||||
BIND(DO1);
|
BIND(DO1);
|
||||||
ldrh(ch1, str1);
|
(this->*str1_load_1chr)(ch1, str1);
|
||||||
cmp(cnt2, 4);
|
cmp(cnt2, 8);
|
||||||
br(LT, DO1_SHORT);
|
br(LT, DO1_SHORT);
|
||||||
|
|
||||||
|
if (str2_isL) {
|
||||||
|
if (!str1_isL) {
|
||||||
|
tst(ch1, 0xff00);
|
||||||
|
br(NE, NOMATCH);
|
||||||
|
}
|
||||||
|
orr(ch1, ch1, ch1, LSL, 8);
|
||||||
|
}
|
||||||
orr(ch1, ch1, ch1, LSL, 16);
|
orr(ch1, ch1, ch1, LSL, 16);
|
||||||
orr(ch1, ch1, ch1, LSL, 32);
|
orr(ch1, ch1, ch1, LSL, 32);
|
||||||
|
|
||||||
sub(cnt2, cnt2, 4);
|
sub(cnt2, cnt2, 8/str2_chr_size);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
mov(tmp3, 0x0001000100010001);
|
mov(tmp3, str2_isL ? 0x0101010101010101 : 0x0001000100010001);
|
||||||
BIND(CH1_LOOP);
|
BIND(CH1_LOOP);
|
||||||
ldr(ch2, Address(str2, cnt2_neg));
|
ldr(ch2, Address(str2, cnt2_neg));
|
||||||
eor(ch2, ch1, ch2);
|
eor(ch2, ch1, ch2);
|
||||||
sub(tmp1, ch2, tmp3);
|
sub(tmp1, ch2, tmp3);
|
||||||
orr(tmp2, ch2, 0x7fff7fff7fff7fff);
|
orr(tmp2, ch2, str2_isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff);
|
||||||
bics(tmp1, tmp1, tmp2);
|
bics(tmp1, tmp1, tmp2);
|
||||||
br(NE, HAS_ZERO);
|
br(NE, HAS_ZERO);
|
||||||
adds(cnt2_neg, cnt2_neg, 8);
|
adds(cnt2_neg, cnt2_neg, 8);
|
||||||
@ -4459,13 +4476,13 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
|
|
||||||
BIND(DO1_SHORT);
|
BIND(DO1_SHORT);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
BIND(DO1_LOOP);
|
BIND(DO1_LOOP);
|
||||||
ldrh(ch2, Address(str2, cnt2_neg));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmpw(ch1, ch2);
|
cmpw(ch1, ch2);
|
||||||
br(EQ, MATCH);
|
br(EQ, MATCH);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LT, DO1_LOOP);
|
br(LT, DO1_LOOP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4473,7 +4490,7 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
mov(result, -1);
|
mov(result, -1);
|
||||||
b(DONE);
|
b(DONE);
|
||||||
BIND(MATCH);
|
BIND(MATCH);
|
||||||
add(result, result_tmp, cnt2_neg, ASR, 1);
|
add(result, result_tmp, cnt2_neg, ASR, str2_chr_shift);
|
||||||
BIND(DONE);
|
BIND(DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1217,7 +1217,7 @@ public:
|
|||||||
Register cnt1, Register cnt2,
|
Register cnt1, Register cnt2,
|
||||||
Register tmp1, Register tmp2,
|
Register tmp1, Register tmp2,
|
||||||
Register tmp3, Register tmp4,
|
Register tmp3, Register tmp4,
|
||||||
int int_cnt1, Register result);
|
int int_cnt1, Register result, int ae);
|
||||||
private:
|
private:
|
||||||
void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo,
|
void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo,
|
||||||
Register src1, Register src2);
|
Register src1, Register src2);
|
||||||
|
Loading…
Reference in New Issue
Block a user