hotspot/src/cpu/ppc/vm/ppc.ad
changeset 35581 dd47cf4734f2
parent 35232 76aed99c0ddd
child 35594 cc13089c6327
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Mon Jan 18 17:31:14 2016 +0100
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Wed Jan 20 16:33:51 2016 +0100
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
 // Copyright 2012, 2015 SAP AG. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
@@ -956,36 +956,40 @@
 // 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 (3*4-current_offset)&31;  // see MacroAssembler::string_indexof_1
 }
 
 int string_indexOf_imm1Node::compute_padding(int current_offset) const {
-  return (2*4-current_offset)&31;
+  return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof_1
+}
+
+int string_indexOfCharNode::compute_padding(int current_offset) const {
+  return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof_1
 }
 
 int string_indexOf_immNode::compute_padding(int current_offset) const {
-  return (3*4-current_offset)&31;
+  return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof(constant needlecount)
 }
 
 int string_indexOfNode::compute_padding(int current_offset) const {
-  return (1*4-current_offset)&31;
+  return (1*4-current_offset)&31;  // see MacroAssembler::string_indexof(variable needlecount)
 }
 
 int string_compareNode::compute_padding(int current_offset) const {
-  return (4*4-current_offset)&31;
+  return (2*4-current_offset)&31;  // see MacroAssembler::string_compare
 }
 
 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;
+  if (opnd_array(3)->constant() < 16) return 0; // For strlen < 16 no nops because loop completely unrolled
+  return (2*4-current_offset)&31;               // Genral case - see MacroAssembler::char_arrays_equalsImm
 }
 
 int string_equalsNode::compute_padding(int current_offset) const {
-  return (7*4-current_offset)&31;
+  return (7*4-current_offset)&31;  // see MacroAssembler::char_arrays_equals
 }
 
 int inlineCallClearArrayNode::compute_padding(int current_offset) const {
-  return (2*4-current_offset)&31;
+  return (2*4-current_offset)&31;  // see MacroAssembler::clear_memory_doubleword
 }
 
 //=============================================================================
@@ -2025,6 +2029,8 @@
     return SpecialStringEquals && !CompactStrings;
   case Op_StrIndexOf:
     return SpecialStringIndexOf && !CompactStrings;
+  case Op_StrIndexOfChar:
+    return SpecialStringIndexOf && !CompactStrings;
   }
 
   return true;  // Per default match rules are supported.
@@ -11034,11 +11040,11 @@
 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
                                   iRegIdst tmp1, iRegIdst tmp2,
-                                  flagsRegCR0 cr0, flagsRegCR1 cr1) %{
+                                  flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
   predicate(SpecialStringIndexOf && !CompactStrings);  // type check implicit by parameter type, See Matcher::match_rule_supported
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
 
-  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
 
   ins_cost(150);
   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
@@ -11050,10 +11056,23 @@
     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
+#ifdef VM_LITTLE_ENDIAN
+      chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
+              (jchar)needle_values->element_value(0).as_byte();
+#else
+      chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
+              (jchar)needle_values->element_value(1).as_byte();
+#endif
+    } 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);
@@ -11073,12 +11092,13 @@
 instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
                              rscratch2RegP needle, immI_1 needlecntImm,
                              iRegIdst tmp1, iRegIdst tmp2,
-                             flagsRegCR0 cr0, flagsRegCR1 cr1) %{
+                             flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
   effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
-         TEMP tmp1, TEMP tmp2);
+         TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
   // 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);
 
@@ -11091,17 +11111,54 @@
     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) {
-      __ string_indexof_1($result$$Register,
-                          $haystack$$Register, $haycnt$$Register,
-                          R0, needle_values->char_at(0),
-                          $tmp1$$Register, $tmp2$$Register);
+    jchar chr;
+    if (java_lang_String::has_coder_field()) {
+      // New compact strings byte array strings
+#ifdef VM_LITTLE_ENDIAN
+      chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
+              (jchar)needle_values->element_value(0).as_byte();
+#else
+      chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
+              (jchar)needle_values->element_value(1).as_byte();
+#endif
     } else {
-      __ string_indexof_1($result$$Register,
-                          $haystack$$Register, $haycnt$$Register,
-                          $needle$$Register, 0,
-                          $tmp1$$Register, $tmp2$$Register);
+      // Old char array strings
+      chr = needle_values->char_at(0);
     }
+    __ string_indexof_1($result$$Register,
+                        $haystack$$Register, $haycnt$$Register,
+                        R0, chr,
+                        $tmp1$$Register, $tmp2$$Register);
+  %}
+  ins_pipe(pipe_class_compare);
+%}
+
+// String_IndexOfChar
+//
+// Assumes register result differs from all input registers.
+//
+// Preserves registers haystack, haycnt
+// Kills     registers tmp1, tmp2
+// 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, regCTR ctr) %{
+  match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
+  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,
+                        $ch$$Register, 0 /* this is not used if the character is already in a register */,
+                        $tmp1$$Register, $tmp2$$Register);
   %}
   ins_pipe(pipe_class_compare);
 %}
@@ -11120,10 +11177,10 @@
 instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
                             iRegPsrc needle, uimmI15 needlecntImm,
                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
-                            flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
+                            flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
-         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
+         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
   // 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() &&
             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
@@ -11153,11 +11210,11 @@
 // Use dst register classes if register gets killed, as it is the case for tmp registers!
 instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
                         iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
-                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
+                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
          TEMP_DEF result,
-         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
+         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
   predicate(SpecialStringIndexOf && !CompactStrings);  // See Matcher::match_rule_supported.
   ins_cost(300);