< 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


4119     }
4120   }
4121 }
4122 
4123 void MacroAssembler::remove_frame(int framesize) {
4124   assert(framesize > 0, "framesize must be > 0");
4125   if (framesize < ((1 << 9) + 2 * wordSize)) {
4126     ldp(rfp, lr, Address(sp, framesize - 2 * wordSize));
4127     add(sp, sp, framesize);
4128   } else {
4129     if (framesize < ((1 << 12) + 2 * wordSize))
4130       add(sp, sp, framesize - 2 * wordSize);
4131     else {
4132       mov(rscratch1, framesize - 2 * wordSize);
4133       add(sp, sp, rscratch1);
4134     }
4135     ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
4136   }
4137 }
4138 

4139 
4140 // Search for str1 in str2 and return index or -1
4141 void MacroAssembler::string_indexof(Register str2, Register str1,
4142                                     Register cnt2, Register cnt1,
4143                                     Register tmp1, Register tmp2,
4144                                     Register tmp3, Register tmp4,
4145                                     int icnt1, Register result) {
4146   Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
4147 
4148   Register ch1 = rscratch1;
4149   Register ch2 = rscratch2;
4150   Register cnt1tmp = tmp1;
4151   Register cnt2tmp = tmp2;
4152   Register cnt1_neg = cnt1;
4153   Register cnt2_neg = cnt2;
4154   Register result_tmp = tmp4;
4155 








4156   // Note, inline_string_indexOf() generates checks:
4157   // if (substr.count > string.count) return -1;
4158   // if (substr.count == 0) return 0;
4159 
4160 // We have two strings, a source string in str2, cnt2 and a pattern string
4161 // in str1, cnt1. Find the 1st occurence of pattern in source or return -1.
4162 
4163 // For larger pattern and source we use a simplified Boyer Moore algorithm.
4164 // With a small pattern and source we use linear scan.
4165 
4166   if (icnt1 == -1) {
4167     cmp(cnt1, 256);             // Use Linear Scan if cnt1 < 8 || cnt1 >= 256
4168     ccmp(cnt1, 8, 0b0000, LO);  // Can't handle skip >= 256 because we use
4169     br(LO, LINEARSEARCH);       // a byte array.
4170     cmp(cnt1, cnt2, LSR, 2);    // Source must be 4 * pattern for BM
4171     br(HS, LINEARSEARCH);
4172   }
4173 
4174 // The Boyer Moore alogorithm is based on the description here:-
4175 //


4225     Label BMADV, BMMATCH, BMCHECKEND;
4226 
4227     Register cnt1end = tmp2;
4228     Register str2end = cnt2;
4229     Register skipch = tmp2;
4230 
4231     // Restrict ASIZE to 128 to reduce stack space/initialisation.
4232     // The presence of chars >= ASIZE in the target string does not affect
4233     // performance, but we must be careful not to initialise them in the stack
4234     // array.
4235     // The presence of chars >= ASIZE in the source string may adversely affect
4236     // performance since we can only advance by one when we encounter one.
4237 
4238       stp(zr, zr, pre(sp, -128));
4239       for (int i = 1; i < 8; i++)
4240           stp(zr, zr, Address(sp, i*16));
4241 
4242       mov(cnt1tmp, 0);
4243       sub(cnt1end, cnt1, 1);
4244     BIND(BCLOOP);
4245       ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
4246       cmp(ch1, 128);
4247       add(cnt1tmp, cnt1tmp, 1);
4248       br(HS, BCSKIP);
4249       strb(cnt1tmp, Address(sp, ch1));
4250     BIND(BCSKIP);
4251       cmp(cnt1tmp, cnt1end);
4252       br(LT, BCLOOP);
4253 
4254       mov(result_tmp, str2);
4255 
4256       sub(cnt2, cnt2, cnt1);
4257       add(str2end, str2, cnt2, LSL, 1);
4258     BIND(BMLOOPSTR2);
4259       sub(cnt1tmp, cnt1, 1);
4260       ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
4261       ldrh(skipch, Address(str2, cnt1tmp, Address::lsl(1)));
4262       cmp(ch1, skipch);
4263       br(NE, BMSKIP);
4264       subs(cnt1tmp, cnt1tmp, 1);
4265       br(LT, BMMATCH);
4266     BIND(BMLOOPSTR1);
4267       ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
4268       ldrh(ch2, Address(str2, cnt1tmp, Address::lsl(1)));
4269       cmp(ch1, ch2);
4270       br(NE, BMSKIP);
4271       subs(cnt1tmp, cnt1tmp, 1);
4272       br(GE, BMLOOPSTR1);
4273     BIND(BMMATCH);
4274       sub(result_tmp, str2, result_tmp);
4275       lsr(result, result_tmp, 1);
4276       add(sp, sp, 128);
4277       b(DONE);
4278     BIND(BMADV);
4279       add(str2, str2, 2);
4280       b(BMCHECKEND);
4281     BIND(BMSKIP);
4282       cmp(skipch, 128);
4283       br(HS, BMADV);
4284       ldrb(ch2, Address(sp, skipch));
4285       add(str2, str2, cnt1, LSL, 1);
4286       sub(str2, str2, ch2, LSL, 1);
4287     BIND(BMCHECKEND);
4288       cmp(str2, str2end);
4289       br(LE, BMLOOPSTR2);
4290       add(sp, sp, 128);
4291       b(NOMATCH);
4292   }
4293 
4294   BIND(LINEARSEARCH);
4295   {
4296     Label DO1, DO2, DO3;
4297 
4298     Register str2tmp = tmp2;
4299     Register first = tmp3;
4300 
4301     if (icnt1 == -1)
4302     {
4303         Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT, LAST_WORD;
4304 
4305         cmp(cnt1, 4);
4306         br(LT, DOSHORT);
4307 
4308         sub(cnt2, cnt2, cnt1);
4309         sub(cnt1, cnt1, 4);
4310         mov(result_tmp, cnt2);
4311 
4312         lea(str1, Address(str1, cnt1, Address::uxtw(1)));
4313         lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4314         sub(cnt1_neg, zr, cnt1, LSL, 1);
4315         sub(cnt2_neg, zr, cnt2, LSL, 1);
4316         ldr(first, Address(str1, cnt1_neg));
4317 
4318       BIND(FIRST_LOOP);
4319         ldr(ch2, Address(str2, cnt2_neg));
4320         cmp(first, ch2);
4321         br(EQ, STR1_LOOP);
4322       BIND(STR2_NEXT);
4323         adds(cnt2_neg, cnt2_neg, 2);
4324         br(LE, FIRST_LOOP);
4325         b(NOMATCH);
4326 
4327       BIND(STR1_LOOP);
4328         adds(cnt1tmp, cnt1_neg, 8);
4329         add(cnt2tmp, cnt2_neg, 8);
4330         br(GE, LAST_WORD);
4331 
4332       BIND(STR1_NEXT);
4333         ldr(ch1, Address(str1, cnt1tmp));
4334         ldr(ch2, Address(str2, cnt2tmp));
4335         cmp(ch1, ch2);
4336         br(NE, STR2_NEXT);
4337         adds(cnt1tmp, cnt1tmp, 8);
4338         add(cnt2tmp, cnt2tmp, 8);
4339         br(LT, STR1_NEXT);
4340 
4341       BIND(LAST_WORD);
4342         ldr(ch1, Address(str1));
4343         sub(str2tmp, str2, cnt1_neg);         // adjust to corresponding
4344         ldr(ch2, Address(str2tmp, cnt2_neg)); // word in str2
4345         cmp(ch1, ch2);
4346         br(NE, STR2_NEXT);
4347         b(MATCH);
4348 
4349       BIND(DOSHORT);
4350         cmp(cnt1, 2);
4351         br(LT, DO1);
4352         br(GT, DO3);
4353     }
4354 
4355     if (icnt1 == 4) {
4356       Label CH1_LOOP;
4357 
4358         ldr(ch1, str1);
4359         sub(cnt2, cnt2, 4);
4360         mov(result_tmp, cnt2);
4361         lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4362         sub(cnt2_neg, zr, cnt2, LSL, 1);
4363 
4364       BIND(CH1_LOOP);
4365         ldr(ch2, Address(str2, cnt2_neg));
4366         cmp(ch1, ch2);
4367         br(EQ, MATCH);
4368         adds(cnt2_neg, cnt2_neg, 2);
4369         br(LE, CH1_LOOP);
4370         b(NOMATCH);
4371     }
4372 
4373     if (icnt1 == -1 || icnt1 == 2) {
4374       Label CH1_LOOP;
4375 
4376       BIND(DO2);
4377         ldrw(ch1, str1);
4378         sub(cnt2, cnt2, 2);
4379         mov(result_tmp, cnt2);
4380         lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4381         sub(cnt2_neg, zr, cnt2, LSL, 1);
4382 
4383       BIND(CH1_LOOP);
4384         ldrw(ch2, Address(str2, cnt2_neg));
4385         cmp(ch1, ch2);
4386         br(EQ, MATCH);
4387         adds(cnt2_neg, cnt2_neg, 2);
4388         br(LE, CH1_LOOP);
4389         b(NOMATCH);
4390     }
4391 
4392     if (icnt1 == -1 || icnt1 == 3) {
4393       Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
4394 
4395       BIND(DO3);
4396         ldrw(first, str1);
4397         ldrh(ch1, Address(str1, 4));
4398 
4399         sub(cnt2, cnt2, 3);
4400         mov(result_tmp, cnt2);
4401         lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4402         sub(cnt2_neg, zr, cnt2, LSL, 1);
4403 
4404       BIND(FIRST_LOOP);
4405         ldrw(ch2, Address(str2, cnt2_neg));
4406         cmpw(first, ch2);
4407         br(EQ, STR1_LOOP);
4408       BIND(STR2_NEXT);
4409         adds(cnt2_neg, cnt2_neg, 2);
4410         br(LE, FIRST_LOOP);
4411         b(NOMATCH);
4412 
4413       BIND(STR1_LOOP);
4414         add(cnt2tmp, cnt2_neg, 4);
4415         ldrh(ch2, Address(str2, cnt2tmp));
4416         cmp(ch1, ch2);
4417         br(NE, STR2_NEXT);
4418         b(MATCH);
4419     }
4420 
4421     if (icnt1 == -1 || icnt1 == 1) {
4422       Label CH1_LOOP, HAS_ZERO;
4423       Label DO1_SHORT, DO1_LOOP;
4424 
4425       BIND(DO1);
4426         ldrh(ch1, str1);
4427         cmp(cnt2, 4);
4428         br(LT, DO1_SHORT);
4429 

4430         orr(ch1, ch1, ch1, LSL, 16);
4431         orr(ch1, ch1, ch1, LSL, 32);
4432 
4433         sub(cnt2, cnt2, 4);
4434         mov(result_tmp, cnt2);
4435         lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4436         sub(cnt2_neg, zr, cnt2, LSL, 1);
4437 
4438         mov(tmp3, 0x0001000100010001);
4439       BIND(CH1_LOOP);
4440         ldr(ch2, Address(str2, cnt2_neg));
4441         eor(ch2, ch1, ch2);
4442         sub(tmp1, ch2, tmp3);
4443         orr(tmp2, ch2, 0x7fff7fff7fff7fff);
4444         bics(tmp1, tmp1, tmp2);
4445         br(NE, HAS_ZERO);
4446         adds(cnt2_neg, cnt2_neg, 8);
4447         br(LT, CH1_LOOP);
4448 
4449         cmp(cnt2_neg, 8);
4450         mov(cnt2_neg, 0);
4451         br(LT, CH1_LOOP);
4452         b(NOMATCH);
4453 
4454       BIND(HAS_ZERO);
4455         rev(tmp1, tmp1);
4456         clz(tmp1, tmp1);
4457         add(cnt2_neg, cnt2_neg, tmp1, LSR, 3);
4458         b(MATCH);
4459 
4460       BIND(DO1_SHORT);
4461         mov(result_tmp, cnt2);
4462         lea(str2, Address(str2, cnt2, Address::uxtw(1)));
4463         sub(cnt2_neg, zr, cnt2, LSL, 1);
4464       BIND(DO1_LOOP);
4465         ldrh(ch2, Address(str2, cnt2_neg));
4466         cmpw(ch1, ch2);
4467         br(EQ, MATCH);
4468         adds(cnt2_neg, cnt2_neg, 2);
4469         br(LT, DO1_LOOP);
4470     }
4471   }
4472   BIND(NOMATCH);
4473     mov(result, -1);
4474     b(DONE);
4475   BIND(MATCH);
4476     add(result, result_tmp, cnt2_neg, ASR, 1);
4477   BIND(DONE);
4478 }
4479 
4480 // Compare strings.
4481 void MacroAssembler::string_compare(Register str1, Register str2,
4482                                     Register cnt1, Register cnt2, Register result,
4483                                     Register tmp1) {
4484   Label LENGTH_DIFF, DONE, SHORT_LOOP, SHORT_STRING,
4485     NEXT_WORD, DIFFERENCE;
4486 
4487   BLOCK_COMMENT("string_compare {");
4488 
4489   // Compute the minimum of the string lengths and save the difference.
4490   subsw(tmp1, cnt1, cnt2);
4491   cselw(cnt2, cnt1, cnt2, Assembler::LE); // min
4492 
4493   // A very short string
4494   cmpw(cnt2, 4);
4495   br(Assembler::LT, SHORT_STRING);
4496 




4119     }
4120   }
4121 }
4122 
4123 void MacroAssembler::remove_frame(int framesize) {
4124   assert(framesize > 0, "framesize must be > 0");
4125   if (framesize < ((1 << 9) + 2 * wordSize)) {
4126     ldp(rfp, lr, Address(sp, framesize - 2 * wordSize));
4127     add(sp, sp, framesize);
4128   } else {
4129     if (framesize < ((1 << 12) + 2 * wordSize))
4130       add(sp, sp, framesize - 2 * wordSize);
4131     else {
4132       mov(rscratch1, framesize - 2 * wordSize);
4133       add(sp, sp, rscratch1);
4134     }
4135     ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
4136   }
4137 }
4138 
4139 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
4140 
4141 // Search for str1 in str2 and return index or -1
4142 void MacroAssembler::string_indexof(Register str2, Register str1,
4143                                     Register cnt2, Register cnt1,
4144                                     Register tmp1, Register tmp2,
4145                                     Register tmp3, Register tmp4,
4146                                     int icnt1, Register result, int ae) {
4147   Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
4148 
4149   Register ch1 = rscratch1;
4150   Register ch2 = rscratch2;
4151   Register cnt1tmp = tmp1;
4152   Register cnt2tmp = tmp2;
4153   Register cnt1_neg = cnt1;
4154   Register cnt2_neg = cnt2;
4155   Register result_tmp = tmp4;
4156 
4157   guarantee(ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU, "unhandled argument encoding");
4158   bool isL = ae == StrIntrinsicNode::LL;
4159   int chr_shift = isL ? 0:1;
4160   int chr_size = isL ? 1:2;
4161   chr_insn load_chr = isL ? (chr_insn)&MacroAssembler::ldrb : (chr_insn)&MacroAssembler::ldrh;
4162   chr_insn load_2chr = isL ? (chr_insn)&MacroAssembler::ldrh : (chr_insn)&MacroAssembler::ldrw;
4163   chr_insn load_4chr = isL ? (chr_insn)&MacroAssembler::ldrw : (chr_insn)&MacroAssembler::ldr;
4164 
4165   // Note, inline_string_indexOf() generates checks:
4166   // if (substr.count > string.count) return -1;
4167   // if (substr.count == 0) return 0;
4168 
4169 // We have two strings, a source string in str2, cnt2 and a pattern string
4170 // in str1, cnt1. Find the 1st occurence of pattern in source or return -1.
4171 
4172 // For larger pattern and source we use a simplified Boyer Moore algorithm.
4173 // With a small pattern and source we use linear scan.
4174 
4175   if (icnt1 == -1) {
4176     cmp(cnt1, 256);             // Use Linear Scan if cnt1 < 8 || cnt1 >= 256
4177     ccmp(cnt1, 8, 0b0000, LO);  // Can't handle skip >= 256 because we use
4178     br(LO, LINEARSEARCH);       // a byte array.
4179     cmp(cnt1, cnt2, LSR, 2);    // Source must be 4 * pattern for BM
4180     br(HS, LINEARSEARCH);
4181   }
4182 
4183 // The Boyer Moore alogorithm is based on the description here:-
4184 //


4234     Label BMADV, BMMATCH, BMCHECKEND;
4235 
4236     Register cnt1end = tmp2;
4237     Register str2end = cnt2;
4238     Register skipch = tmp2;
4239 
4240     // Restrict ASIZE to 128 to reduce stack space/initialisation.
4241     // The presence of chars >= ASIZE in the target string does not affect
4242     // performance, but we must be careful not to initialise them in the stack
4243     // array.
4244     // The presence of chars >= ASIZE in the source string may adversely affect
4245     // performance since we can only advance by one when we encounter one.
4246 
4247       stp(zr, zr, pre(sp, -128));
4248       for (int i = 1; i < 8; i++)
4249           stp(zr, zr, Address(sp, i*16));
4250 
4251       mov(cnt1tmp, 0);
4252       sub(cnt1end, cnt1, 1);
4253     BIND(BCLOOP);
4254       (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift)));
4255       cmp(ch1, 128);
4256       add(cnt1tmp, cnt1tmp, 1);
4257       br(HS, BCSKIP);
4258       strb(cnt1tmp, Address(sp, ch1));
4259     BIND(BCSKIP);
4260       cmp(cnt1tmp, cnt1end);
4261       br(LT, BCLOOP);
4262 
4263       mov(result_tmp, str2);
4264 
4265       sub(cnt2, cnt2, cnt1);
4266       add(str2end, str2, cnt2, LSL, chr_shift);
4267     BIND(BMLOOPSTR2);
4268       sub(cnt1tmp, cnt1, 1);
4269       (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift)));
4270       (this->*load_chr)(skipch, Address(str2, cnt1tmp, Address::lsl(chr_shift)));
4271       cmp(ch1, skipch);
4272       br(NE, BMSKIP);
4273       subs(cnt1tmp, cnt1tmp, 1);
4274       br(LT, BMMATCH);
4275     BIND(BMLOOPSTR1);
4276       (this->*load_chr)(ch1, Address(str1, cnt1tmp, Address::lsl(chr_shift)));
4277       (this->*load_chr)(ch2, Address(str2, cnt1tmp, Address::lsl(chr_shift)));
4278       cmp(ch1, ch2);
4279       br(NE, BMSKIP);
4280       subs(cnt1tmp, cnt1tmp, 1);
4281       br(GE, BMLOOPSTR1);
4282     BIND(BMMATCH);
4283       sub(result, str2, result_tmp);
4284       if (!isL) lsr(result, result, 1);
4285       add(sp, sp, 128);
4286       b(DONE);
4287     BIND(BMADV);
4288       add(str2, str2, chr_size);
4289       b(BMCHECKEND);
4290     BIND(BMSKIP);
4291       cmp(skipch, 128);
4292       br(HS, BMADV);
4293       ldrb(ch2, Address(sp, skipch));
4294       add(str2, str2, cnt1, LSL, chr_shift);
4295       sub(str2, str2, ch2, LSL, chr_shift);
4296     BIND(BMCHECKEND);
4297       cmp(str2, str2end);
4298       br(LE, BMLOOPSTR2);
4299       add(sp, sp, 128);
4300       b(NOMATCH);
4301   }
4302 
4303   BIND(LINEARSEARCH);
4304   {
4305     Label DO1, DO2, DO3;
4306 
4307     Register str2tmp = tmp2;
4308     Register first = tmp3;
4309 
4310     if (icnt1 == -1)
4311     {
4312         Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT, LAST_WORD;
4313 
4314         cmp(cnt1, 4);
4315         br(LT, DOSHORT);
4316 
4317         sub(cnt2, cnt2, cnt1);
4318         sub(cnt1, cnt1, 4);
4319         mov(result_tmp, cnt2);
4320 
4321         lea(str1, Address(str1, cnt1, Address::lsl(chr_shift)));
4322         lea(str2, Address(str2, cnt2, Address::lsl(chr_shift)));
4323         sub(cnt1_neg, zr, cnt1, LSL, chr_shift);
4324         sub(cnt2_neg, zr, cnt2, LSL, chr_shift);
4325         (this->*load_4chr)(first, Address(str1, cnt1_neg));
4326 
4327       BIND(FIRST_LOOP);
4328         (this->*load_4chr)(ch2, Address(str2, cnt2_neg));
4329         cmp(first, ch2);
4330         br(EQ, STR1_LOOP);
4331       BIND(STR2_NEXT);
4332         adds(cnt2_neg, cnt2_neg, chr_size);
4333         br(LE, FIRST_LOOP);
4334         b(NOMATCH);
4335 
4336       BIND(STR1_LOOP);
4337         adds(cnt1tmp, cnt1_neg, 4*chr_size);
4338         add(cnt2tmp, cnt2_neg, 4*chr_size);
4339         br(GE, LAST_WORD);
4340 
4341       BIND(STR1_NEXT);
4342         (this->*load_4chr)(ch1, Address(str1, cnt1tmp));
4343         (this->*load_4chr)(ch2, Address(str2, cnt2tmp));
4344         cmp(ch1, ch2);
4345         br(NE, STR2_NEXT);
4346         adds(cnt1tmp, cnt1tmp, 4*chr_size);
4347         add(cnt2tmp, cnt2tmp, 4*chr_size);
4348         br(LT, STR1_NEXT);
4349 
4350       BIND(LAST_WORD);
4351         (this->*load_4chr)(ch1, Address(str1));
4352         sub(str2tmp, str2, cnt1_neg);         // adjust to corresponding
4353         (this->*load_4chr)(ch2, Address(str2tmp, cnt2_neg)); // word in str2
4354         cmp(ch1, ch2);
4355         br(NE, STR2_NEXT);
4356         b(MATCH);
4357 
4358       BIND(DOSHORT);
4359         cmp(cnt1, 2);
4360         br(LT, DO1);
4361         br(GT, DO3);
4362     }
4363 
4364     if (icnt1 == 4) {
4365       Label CH1_LOOP;
4366 
4367         (this->*load_4chr)(ch1, str1);
4368         sub(cnt2, cnt2, 4);
4369         mov(result_tmp, cnt2);
4370         lea(str2, Address(str2, cnt2, Address::lsl(chr_shift)));
4371         sub(cnt2_neg, zr, cnt2, LSL, chr_shift);
4372 
4373       BIND(CH1_LOOP);
4374         (this->*load_4chr)(ch2, Address(str2, cnt2_neg));
4375         cmp(ch1, ch2);
4376         br(EQ, MATCH);
4377         adds(cnt2_neg, cnt2_neg, chr_size);
4378         br(LE, CH1_LOOP);
4379         b(NOMATCH);
4380     }
4381 
4382     if (icnt1 == -1 || icnt1 == 2) {
4383       Label CH1_LOOP;
4384 
4385       BIND(DO2);
4386         (this->*load_2chr)(ch1, str1);
4387         sub(cnt2, cnt2, 2);
4388         mov(result_tmp, cnt2);
4389         lea(str2, Address(str2, cnt2, Address::lsl(chr_shift)));
4390         sub(cnt2_neg, zr, cnt2, LSL, chr_shift);
4391 
4392       BIND(CH1_LOOP);
4393         (this->*load_2chr)(ch2, Address(str2, cnt2_neg));
4394         cmp(ch1, ch2);
4395         br(EQ, MATCH);
4396         adds(cnt2_neg, cnt2_neg, chr_size);
4397         br(LE, CH1_LOOP);
4398         b(NOMATCH);
4399     }
4400 
4401     if (icnt1 == -1 || icnt1 == 3) {
4402       Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
4403 
4404       BIND(DO3);
4405         (this->*load_2chr)(first, str1);
4406         (this->*load_chr)(ch1, Address(str1, 2*chr_size));
4407 
4408         sub(cnt2, cnt2, 3);
4409         mov(result_tmp, cnt2);
4410         lea(str2, Address(str2, cnt2, Address::lsl(chr_shift)));
4411         sub(cnt2_neg, zr, cnt2, LSL, chr_shift);
4412 
4413       BIND(FIRST_LOOP);
4414         (this->*load_2chr)(ch2, Address(str2, cnt2_neg));
4415         cmpw(first, ch2);
4416         br(EQ, STR1_LOOP);
4417       BIND(STR2_NEXT);
4418         adds(cnt2_neg, cnt2_neg, chr_size);
4419         br(LE, FIRST_LOOP);
4420         b(NOMATCH);
4421 
4422       BIND(STR1_LOOP);
4423         add(cnt2tmp, cnt2_neg, 2*chr_size);
4424         (this->*load_chr)(ch2, Address(str2, cnt2tmp));
4425         cmp(ch1, ch2);
4426         br(NE, STR2_NEXT);
4427         b(MATCH);
4428     }
4429 
4430     if (icnt1 == -1 || icnt1 == 1) {
4431       Label CH1_LOOP, HAS_ZERO;
4432       Label DO1_SHORT, DO1_LOOP;
4433 
4434       BIND(DO1);
4435         (this->*load_chr)(ch1, str1);
4436         cmp(cnt2, 8);
4437         br(LT, DO1_SHORT);
4438 
4439         if (isL) orr(ch1, ch1, ch1, LSL, 8);
4440         orr(ch1, ch1, ch1, LSL, 16);
4441         orr(ch1, ch1, ch1, LSL, 32);
4442 
4443         sub(cnt2, cnt2, 8/chr_size);
4444         mov(result_tmp, cnt2);
4445         lea(str2, Address(str2, cnt2, Address::lsl(chr_shift)));
4446         sub(cnt2_neg, zr, cnt2, LSL, chr_shift);
4447 
4448         mov(tmp3, isL ? 0x0101010101010101 : 0x0001000100010001);
4449       BIND(CH1_LOOP);
4450         ldr(ch2, Address(str2, cnt2_neg));
4451         eor(ch2, ch1, ch2);
4452         sub(tmp1, ch2, tmp3);
4453         orr(tmp2, ch2, isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff);
4454         bics(tmp1, tmp1, tmp2);
4455         br(NE, HAS_ZERO);
4456         adds(cnt2_neg, cnt2_neg, 8);
4457         br(LT, CH1_LOOP);
4458 
4459         cmp(cnt2_neg, 8);
4460         mov(cnt2_neg, 0);
4461         br(LT, CH1_LOOP);
4462         b(NOMATCH);
4463 
4464       BIND(HAS_ZERO);
4465         rev(tmp1, tmp1);
4466         clz(tmp1, tmp1);
4467         add(cnt2_neg, cnt2_neg, tmp1, LSR, 3);
4468         b(MATCH);
4469 
4470       BIND(DO1_SHORT);
4471         mov(result_tmp, cnt2);
4472         lea(str2, Address(str2, cnt2, Address::lsl(chr_shift)));
4473         sub(cnt2_neg, zr, cnt2, LSL, chr_shift);
4474       BIND(DO1_LOOP);
4475         (this->*load_chr)(ch2, Address(str2, cnt2_neg));
4476         cmpw(ch1, ch2);
4477         br(EQ, MATCH);
4478         adds(cnt2_neg, cnt2_neg, chr_size);
4479         br(LT, DO1_LOOP);
4480     }
4481   }
4482   BIND(NOMATCH);
4483     mov(result, -1);
4484     b(DONE);
4485   BIND(MATCH);
4486     add(result, result_tmp, cnt2_neg, ASR, chr_shift);
4487   BIND(DONE);
4488 }
4489 
4490 // Compare strings.
4491 void MacroAssembler::string_compare(Register str1, Register str2,
4492                                     Register cnt1, Register cnt2, Register result,
4493                                     Register tmp1) {
4494   Label LENGTH_DIFF, DONE, SHORT_LOOP, SHORT_STRING,
4495     NEXT_WORD, DIFFERENCE;
4496 
4497   BLOCK_COMMENT("string_compare {");
4498 
4499   // Compute the minimum of the string lengths and save the difference.
4500   subsw(tmp1, cnt1, cnt2);
4501   cselw(cnt2, cnt1, cnt2, Assembler::LE); // min
4502 
4503   // A very short string
4504   cmpw(cnt2, 4);
4505   br(Assembler::LT, SHORT_STRING);
4506 


< prev index next >