< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.cpp

Print this page
rev 11237 : 8156839: aarch64: indexOf does not support CompactStrings
Summary: Add support for LL,UL and LU to indexOf intrinsic
Reviewed-by: aph

@@ -4134,27 +4134,43 @@
     }
     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 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;
 
+  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:
   // 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,11 +4256,11 @@
           stp(zr, zr, Address(sp, i*16));
 
       mov(cnt1tmp, 0);
       sub(cnt1end, cnt1, 1);
     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);
       add(cnt1tmp, cnt1tmp, 1);
       br(HS, BCSKIP);
       strb(cnt1tmp, Address(sp, ch1));
     BIND(BCSKIP);

@@ -4252,40 +4268,40 @@
       br(LT, BCLOOP);
 
       mov(result_tmp, str2);
 
       sub(cnt2, cnt2, cnt1);
-      add(str2end, str2, cnt2, LSL, 1);
+      add(str2end, str2, cnt2, LSL, str2_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->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
+      (this->*str2_load_1chr)(skipch, Address(str2, cnt1tmp, Address::lsl(str2_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->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
+      (this->*str2_load_1chr)(ch2, Address(str2, cnt1tmp, Address::lsl(str2_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 (!str2_isL) lsr(result, result, 1);
       add(sp, sp, 128);
       b(DONE);
     BIND(BMADV);
-      add(str2, str2, 2);
+      add(str2, 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, str2_chr_shift);
+      sub(str2, str2, ch2, LSL, str2_chr_shift);
     BIND(BMCHECKEND);
       cmp(str2, str2end);
       br(LE, BMLOOPSTR2);
       add(sp, sp, 128);
       b(NOMATCH);

@@ -4298,151 +4314,152 @@
     Register str2tmp = tmp2;
     Register first = tmp3;
 
     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);
 
         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));
+        lea(str1, Address(str1, cnt1, Address::lsl(str1_chr_shift)));
+        lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
+        sub(cnt1_neg, zr, cnt1, LSL, str1_chr_shift);
+        sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
+        (this->*str1_load_1chr)(first, Address(str1, cnt1_neg));
 
       BIND(FIRST_LOOP);
-        ldr(ch2, Address(str2, cnt2_neg));
+        (this->*str2_load_1chr)(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, str2_chr_size);
         br(LE, FIRST_LOOP);
         b(NOMATCH);
 
       BIND(STR1_LOOP);
-        adds(cnt1tmp, cnt1_neg, 8);
-        add(cnt2tmp, cnt2_neg, 8);
-        br(GE, LAST_WORD);
+        adds(cnt1tmp, cnt1_neg, str1_chr_size);
+        add(cnt2tmp, cnt2_neg, str2_chr_size);
+        br(GE, MATCH);
 
       BIND(STR1_NEXT);
-        ldr(ch1, Address(str1, cnt1tmp));
-        ldr(ch2, Address(str2, cnt2tmp));
+        (this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp));
+        (this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
         cmp(ch1, ch2);
         br(NE, STR2_NEXT);
-        adds(cnt1tmp, cnt1tmp, 8);
-        add(cnt2tmp, cnt2tmp, 8);
+        adds(cnt1tmp, cnt1tmp, str1_chr_size);
+        add(cnt2tmp, cnt2tmp, str2_chr_size);
         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);
+      if (str1_isL == str2_isL) {
         cmp(cnt1, 2);
         br(LT, DO1);
         br(GT, DO3);
     }
+    }
 
     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(str2_chr_shift)));
+        sub(cnt2_neg, zr, cnt2, LSL, str2_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, str2_chr_size);
         br(LE, CH1_LOOP);
         b(NOMATCH);
     }
 
-    if (icnt1 == -1 || icnt1 == 2) {
+    if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 2) {
       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(str2_chr_shift)));
+        sub(cnt2_neg, zr, cnt2, LSL, str2_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, str2_chr_size);
         br(LE, CH1_LOOP);
         b(NOMATCH);
     }
 
-    if (icnt1 == -1 || icnt1 == 3) {
+    if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 3) {
       Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
 
       BIND(DO3);
-        ldrw(first, str1);
-        ldrh(ch1, Address(str1, 4));
+        (this->*load_2chr)(first, str1);
+        (this->*str1_load_1chr)(ch1, Address(str1, 2*str1_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(str2_chr_shift)));
+        sub(cnt2_neg, zr, cnt2, LSL, str2_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, str2_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*str2_chr_size);
+        (this->*str2_load_1chr)(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);
+        (this->*str1_load_1chr)(ch1, str1);
+        cmp(cnt2, 8);
         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, 32);
 
-        sub(cnt2, cnt2, 4);
+        sub(cnt2, cnt2, 8/str2_chr_size);
         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(str2_chr_shift)));
+        sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
 
-        mov(tmp3, 0x0001000100010001);
+        mov(tmp3, str2_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, str2_isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff);
         bics(tmp1, tmp1, tmp2);
         br(NE, HAS_ZERO);
         adds(cnt2_neg, cnt2_neg, 8);
         br(LT, CH1_LOOP);
 

@@ -4457,25 +4474,25 @@
         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);
+        lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
+        sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
       BIND(DO1_LOOP);
-        ldrh(ch2, Address(str2, cnt2_neg));
+        (this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
         cmpw(ch1, ch2);
         br(EQ, MATCH);
-        adds(cnt2_neg, cnt2_neg, 2);
+        adds(cnt2_neg, cnt2_neg, str2_chr_size);
         br(LT, DO1_LOOP);
     }
   }
   BIND(NOMATCH);
     mov(result, -1);
     b(DONE);
   BIND(MATCH);
-    add(result, result_tmp, cnt2_neg, ASR, 1);
+    add(result, result_tmp, cnt2_neg, ASR, str2_chr_shift);
   BIND(DONE);
 }
 
 // Compare strings.
 void MacroAssembler::string_compare(Register str1, Register str2,
< prev index next >