< prev index next >

src/cpu/ppc/vm/ppc.ad

Print this page
rev 9944 : 8145336: PPC64: fix string intrinsics after CompactStrings change

@@ -954,27 +954,31 @@
 // Compute padding required for nodes which need alignment. The padding
 // is the number of bytes (not instructions) which will be inserted before
 // the instruction. The padding must match the size of a NOP instruction.
 
 int string_indexOf_imm1_charNode::compute_padding(int current_offset) const {
-  return (3*4-current_offset)&31;
+  return (2*4-current_offset)&31;
 }
 
 int string_indexOf_imm1Node::compute_padding(int current_offset) const {
   return (2*4-current_offset)&31;
 }
 
+int string_indexOfCharNode::compute_padding(int current_offset) const {
+  return (2*4-current_offset)&31;
+}
+
 int string_indexOf_immNode::compute_padding(int current_offset) const {
   return (3*4-current_offset)&31;
 }
 
 int string_indexOfNode::compute_padding(int current_offset) const {
   return (1*4-current_offset)&31;
 }
 
 int string_compareNode::compute_padding(int current_offset) const {
-  return (4*4-current_offset)&31;
+  return (6*4-current_offset)&31;
 }
 
 int string_equals_immNode::compute_padding(int current_offset) const {
   if (opnd_array(3)->constant() < 16) return 0; // Don't insert nops for short version (loop completely unrolled).
   return (2*4-current_offset)&31;

@@ -2023,10 +2027,12 @@
     return SpecialStringCompareTo && !CompactStrings;
   case Op_StrEquals:
     return SpecialStringEquals && !CompactStrings;
   case Op_StrIndexOf:
     return SpecialStringIndexOf && !CompactStrings;
+  case Op_StrIndexOfChar:
+    return SpecialStringIndexOf && !CompactStrings;
   }
 
   return true;  // Per default match rules are supported.
 }
 

@@ -11048,14 +11054,22 @@
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     immPOper *needleOper = (immPOper *)$needleImm;
     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
-
+    jchar chr;
+    if (java_lang_String::has_coder_field()) {
+      // New compact strings byte array strings
+      chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
+              (jchar)needle_values->element_value(1).as_byte();
+    } else {
+      // Old char array strings
+      chr = needle_values->char_at(0);
+    }
     __ string_indexof_1($result$$Register,
                         $haystack$$Register, $haycnt$$Register,
-                        R0, needle_values->char_at(0),
+                        R0, chr,
                         $tmp1$$Register, $tmp2$$Register);
   %}
   ins_pipe(pipe_class_compare);
 %}
 

@@ -11076,11 +11090,12 @@
                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
   effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
          TEMP tmp1, TEMP tmp2);
   // Required for EA: check if it is still a type_array.
-  predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
+  predicate(SpecialStringIndexOf && !CompactStrings &&
+            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
   ins_cost(180);
 
   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
 

@@ -11089,21 +11104,53 @@
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
     guarantee(needle_values, "sanity");
-    if (needle_values != NULL) {
+    jchar chr;
+    if (java_lang_String::has_coder_field()) {
+      // New compact strings byte array strings
+      chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
+              (jchar)needle_values->element_value(1).as_byte();
+    } else {
+      // Old char array strings
+      chr = needle_values->char_at(0);
+    }
       __ string_indexof_1($result$$Register,
                           $haystack$$Register, $haycnt$$Register,
-                          R0, needle_values->char_at(0),
+                        R0, chr,
                           $tmp1$$Register, $tmp2$$Register);
-    } else {
+  %}
+  ins_pipe(pipe_class_compare);
+%}
+
+// String_IndexOfChar
+//
+// Assumes register result differs from all input registers.
+//
+// Preserves registers haystack, haycnt
+// Kills     registers tmp1, tmp2, needle
+// Defines   registers result
+//
+// Use dst register classes if register gets killed, as it is the case for tmp registers!
+instruct string_indexOfChar(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
+                            iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
+                            flagsRegCR0 cr0, flagsRegCR1 cr1) %{
+  match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2);
+  predicate(SpecialStringIndexOf && !CompactStrings);
+  ins_cost(180);
+
+  ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
+
+  format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
+            " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
+  ins_encode %{
       __ string_indexof_1($result$$Register,
                           $haystack$$Register, $haycnt$$Register,
-                          $needle$$Register, 0,
+                        $ch$$Register, 0 /* this is not used if the character is already in a register */,
                           $tmp1$$Register, $tmp2$$Register);
-    }
   %}
   ins_pipe(pipe_class_compare);
 %}
 
 // String_IndexOf.
< prev index next >