< prev index next >

src/cpu/ppc/vm/ppc.ad

Print this page
rev 10235 : 8149655: PPC64: Implement CompactString intrinsics
Reviewed-by: goetz
   1 //
   2 // Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright (c) 2012, 2015 SAP SE. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //


2007 const bool Matcher::match_rule_supported(int opcode) {
2008   if (!has_match_rule(opcode))
2009     return false;
2010 
2011   switch (opcode) {
2012   case Op_SqrtD:
2013     return VM_Version::has_fsqrt();
2014   case Op_CountLeadingZerosI:
2015   case Op_CountLeadingZerosL:
2016   case Op_CountTrailingZerosI:
2017   case Op_CountTrailingZerosL:
2018     if (!UseCountLeadingZerosInstructionsPPC64)
2019       return false;
2020     break;
2021 
2022   case Op_PopCountI:
2023   case Op_PopCountL:
2024     return (UsePopCountInstruction && VM_Version::has_popcntw());
2025 
2026   case Op_StrComp:
2027     return SpecialStringCompareTo && !CompactStrings;
2028   case Op_StrEquals:
2029     return SpecialStringEquals && !CompactStrings;
2030   case Op_StrIndexOf:
2031     return SpecialStringIndexOf && !CompactStrings;
2032   case Op_StrIndexOfChar:
2033     return SpecialStringIndexOf && !CompactStrings;
2034   }
2035 
2036   return true;  // Per default match rules are supported.
2037 }
2038 
2039 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
2040 
2041   // TODO
2042   // identify extra cases that we might want to provide match rules for
2043   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
2044   bool ret_value = match_rule_supported(opcode);
2045   // Add rules here.
2046 
2047   return ret_value;  // Per default match rules are supported.
2048 }
2049 
2050 const int Matcher::float_pressure(int default_pressure_threshold) {
2051   return default_pressure_threshold;
2052 }
2053 


11005   %}
11006   ins_pipe(pipe_class_default);
11007 %}
11008 
11009 // Clear-array with dynamic array-size.
11010 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11011   match(Set dummy (ClearArray cnt base));
11012   effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11013   ins_cost(MEMORY_REF_COST);
11014 
11015   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11016 
11017   format %{ "ClearArray $cnt, $base" %}
11018   ins_encode %{
11019     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11020     __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0
11021   %}
11022   ins_pipe(pipe_class_default);
11023 %}
11024 


































































































































































































































































































































































































































































































































































































11025 // String_IndexOf for needle of length 1.
11026 //
11027 // Match needle into immediate operands: no loadConP node needed. Saves one
11028 // register and two instructions over string_indexOf_imm1Node.
11029 //
11030 // Assumes register result differs from all input registers.
11031 //
11032 // Preserves registers haystack, haycnt
11033 // Kills     registers tmp1, tmp2
11034 // Defines   registers result
11035 //
11036 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11037 //
11038 // Unfortunately this does not match too often. In many situations the AddP is used
11039 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
11040 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11041                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
11042                                   iRegIdst tmp1, iRegIdst tmp2,
11043                                   flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11044   predicate(SpecialStringIndexOf && !CompactStrings);  // type check implicit by parameter type, See Matcher::match_rule_supported
11045   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11046 
11047   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11048 
11049   ins_cost(150);
11050   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11051             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11052 
11053   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
11054   ins_encode %{
11055     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11056     immPOper *needleOper = (immPOper *)$needleImm;
11057     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11058     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11059     jchar chr;
11060     if (java_lang_String::has_coder_field()) {
11061       // New compact strings byte array strings
11062 #ifdef VM_LITTLE_ENDIAN
11063       chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
11064               (jchar)needle_values->element_value(0).as_byte();
11065 #else
11066       chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
11067               (jchar)needle_values->element_value(1).as_byte();
11068 #endif
11069     } else {
11070       // Old char array strings
11071       chr = needle_values->char_at(0);
11072     }
11073     __ string_indexof_1($result$$Register,
11074                         $haystack$$Register, $haycnt$$Register,
11075                         R0, chr,
11076                         $tmp1$$Register, $tmp2$$Register);
11077   %}
11078   ins_pipe(pipe_class_compare);
11079 %}
11080 
11081 // String_IndexOf for needle of length 1.
11082 //
11083 // Special case requires less registers and emits less instructions.
11084 //
11085 // Assumes register result differs from all input registers.
11086 //
11087 // Preserves registers haystack, haycnt


11098          TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11099   // Required for EA: check if it is still a type_array.
11100   predicate(SpecialStringIndexOf && !CompactStrings &&
11101             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11102             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11103   ins_cost(180);
11104 
11105   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11106 
11107   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11108             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11109   ins_encode %{
11110     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11111     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11112     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11113     guarantee(needle_values, "sanity");
11114     jchar chr;
11115     if (java_lang_String::has_coder_field()) {
11116       // New compact strings byte array strings
11117 #ifdef VM_LITTLE_ENDIAN
11118       chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
11119               (jchar)needle_values->element_value(0).as_byte();
11120 #else
11121       chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
11122               (jchar)needle_values->element_value(1).as_byte();
11123 #endif
11124     } else {
11125       // Old char array strings
11126       chr = needle_values->char_at(0);
11127     }
11128     __ string_indexof_1($result$$Register,
11129                         $haystack$$Register, $haycnt$$Register,
11130                         R0, chr,
11131                         $tmp1$$Register, $tmp2$$Register);
11132   %}
11133   ins_pipe(pipe_class_compare);
11134 %}
11135 
11136 // String_IndexOfChar
11137 //
11138 // Assumes register result differs from all input registers.
11139 //
11140 // Preserves registers haystack, haycnt
11141 // Kills     registers tmp1, tmp2
11142 // Defines   registers result


11304 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11305   match(Set dst (MinI src1 src2));
11306   ins_cost(DEFAULT_COST*6);
11307 
11308   expand %{
11309     iRegLdst src1s;
11310     iRegLdst src2s;
11311     iRegLdst diff;
11312     iRegLdst sm;
11313     iRegLdst doz; // difference or zero
11314     convI2L_reg(src1s, src1); // Ensure proper sign extension.
11315     convI2L_reg(src2s, src2); // Ensure proper sign extension.
11316     subL_reg_reg(diff, src2s, src1s);
11317     // Need to consider >=33 bit result, therefore we need signmaskL.
11318     signmask64L_regL(sm, diff);
11319     andL_reg_reg(doz, diff, sm); // <=0
11320     addI_regL_regL(dst, doz, src1s);
11321   %}
11322 %}
11323 














11324 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11325   match(Set dst (MaxI src1 src2));
11326   ins_cost(DEFAULT_COST*6);
11327 
11328   expand %{
11329     iRegLdst src1s;
11330     iRegLdst src2s;
11331     iRegLdst diff;
11332     iRegLdst sm;
11333     iRegLdst doz; // difference or zero
11334     convI2L_reg(src1s, src1); // Ensure proper sign extension.
11335     convI2L_reg(src2s, src2); // Ensure proper sign extension.
11336     subL_reg_reg(diff, src2s, src1s);
11337     // Need to consider >=33 bit result, therefore we need signmaskL.
11338     signmask64L_regL(sm, diff);
11339     andcL_reg_reg(doz, diff, sm); // >=0
11340     addI_regL_regL(dst, doz, src1s);
11341   %}
11342 %}
11343 














11344 //---------- Population Count Instructions ------------------------------------
11345 
11346 // Popcnt for Power7.
11347 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
11348   match(Set dst (PopCountI src));
11349   predicate(UsePopCountInstruction && VM_Version::has_popcntw());
11350   ins_cost(DEFAULT_COST);
11351 
11352   format %{ "POPCNTW $dst, $src" %}
11353   size(4);
11354   ins_encode %{
11355     // TODO: PPC port $archOpcode(ppc64Opcode_popcntb);
11356     __ popcntw($dst$$Register, $src$$Register);
11357   %}
11358   ins_pipe(pipe_class_default);
11359 %}
11360 
11361 // Popcnt for Power7.
11362 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
11363   predicate(UsePopCountInstruction && VM_Version::has_popcntw());


   1 //
   2 // Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright (c) 2012, 2016 SAP SE. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //


2007 const bool Matcher::match_rule_supported(int opcode) {
2008   if (!has_match_rule(opcode))
2009     return false;
2010 
2011   switch (opcode) {
2012   case Op_SqrtD:
2013     return VM_Version::has_fsqrt();
2014   case Op_CountLeadingZerosI:
2015   case Op_CountLeadingZerosL:
2016   case Op_CountTrailingZerosI:
2017   case Op_CountTrailingZerosL:
2018     if (!UseCountLeadingZerosInstructionsPPC64)
2019       return false;
2020     break;
2021 
2022   case Op_PopCountI:
2023   case Op_PopCountL:
2024     return (UsePopCountInstruction && VM_Version::has_popcntw());
2025 
2026   case Op_StrComp:
2027     return SpecialStringCompareTo;
2028   case Op_StrEquals:
2029     return SpecialStringEquals;
2030   case Op_StrIndexOf:
2031     return SpecialStringIndexOf;
2032   case Op_StrIndexOfChar:
2033     return SpecialStringIndexOf;
2034   }
2035 
2036   return true;  // Per default match rules are supported.
2037 }
2038 
2039 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
2040 
2041   // TODO
2042   // identify extra cases that we might want to provide match rules for
2043   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
2044   bool ret_value = match_rule_supported(opcode);
2045   // Add rules here.
2046 
2047   return ret_value;  // Per default match rules are supported.
2048 }
2049 
2050 const int Matcher::float_pressure(int default_pressure_threshold) {
2051   return default_pressure_threshold;
2052 }
2053 


11005   %}
11006   ins_pipe(pipe_class_default);
11007 %}
11008 
11009 // Clear-array with dynamic array-size.
11010 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11011   match(Set dummy (ClearArray cnt base));
11012   effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11013   ins_cost(MEMORY_REF_COST);
11014 
11015   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11016 
11017   format %{ "ClearArray $cnt, $base" %}
11018   ins_encode %{
11019     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11020     __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0
11021   %}
11022   ins_pipe(pipe_class_default);
11023 %}
11024 
11025 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11026                          iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11027   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11028   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11029   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11030   ins_cost(300);
11031   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11032   ins_encode %{
11033     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11034     __ string_compare($str1$$Register, $str2$$Register,
11035                       $cnt1$$Register, $cnt2$$Register,
11036                       $tmp$$Register,
11037                       $result$$Register, StrIntrinsicNode::LL);
11038   %}
11039   ins_pipe(pipe_class_default);
11040 %}
11041 
11042 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11043                          iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11044   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11045   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11046   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11047   ins_cost(300);
11048   format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11049   ins_encode %{
11050     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11051     __ string_compare($str1$$Register, $str2$$Register,
11052                       $cnt1$$Register, $cnt2$$Register,
11053                       $tmp$$Register,
11054                       $result$$Register, StrIntrinsicNode::UU);
11055   %}
11056   ins_pipe(pipe_class_default);
11057 %}
11058 
11059 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11060                           iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11061   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11062   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11063   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11064   ins_cost(300);
11065   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11066   ins_encode %{
11067     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11068     __ string_compare($str1$$Register, $str2$$Register,
11069                       $cnt1$$Register, $cnt2$$Register,
11070                       $tmp$$Register,
11071                       $result$$Register, StrIntrinsicNode::LU);
11072   %}
11073   ins_pipe(pipe_class_default);
11074 %}
11075 
11076 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11077                           iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11078   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11079   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11080   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11081   ins_cost(300);
11082   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11083   ins_encode %{
11084     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11085     __ string_compare($str2$$Register, $str1$$Register,
11086                       $cnt2$$Register, $cnt1$$Register,
11087                       $tmp$$Register,
11088                       $result$$Register, StrIntrinsicNode::UL);
11089   %}
11090   ins_pipe(pipe_class_default);
11091 %}
11092 
11093 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11094                         iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11095   predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11096   match(Set result (StrEquals (Binary str1 str2) cnt));
11097   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11098   ins_cost(300);
11099   format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11100   ins_encode %{
11101     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11102     __ array_equals(false, $str1$$Register, $str2$$Register,
11103                     $cnt$$Register, $tmp$$Register,
11104                     $result$$Register, true /* byte */);
11105   %}
11106   ins_pipe(pipe_class_default);
11107 %}
11108 
11109 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11110                         iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11111   predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
11112   match(Set result (StrEquals (Binary str1 str2) cnt));
11113   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11114   ins_cost(300);
11115   format %{ "String Equals char[]  $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11116   ins_encode %{
11117     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11118     __ array_equals(false, $str1$$Register, $str2$$Register,
11119                     $cnt$$Register, $tmp$$Register,
11120                     $result$$Register, false /* byte */);
11121   %}
11122   ins_pipe(pipe_class_default);
11123 %}
11124 
11125 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11126                        iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
11127   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
11128   match(Set result (AryEq ary1 ary2));
11129   effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11130   ins_cost(300);
11131   format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11132   ins_encode %{
11133     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11134     __ array_equals(true, $ary1$$Register, $ary2$$Register,
11135                     $tmp1$$Register, $tmp2$$Register,
11136                     $result$$Register, true /* byte */);
11137   %}
11138   ins_pipe(pipe_class_default);
11139 %}
11140 
11141 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
11142                        iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
11143   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
11144   match(Set result (AryEq ary1 ary2));
11145   effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
11146   ins_cost(300);
11147   format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
11148   ins_encode %{
11149     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11150     __ array_equals(true, $ary1$$Register, $ary2$$Register,
11151                     $tmp1$$Register, $tmp2$$Register,
11152                     $result$$Register, false /* byte */);
11153   %}
11154   ins_pipe(pipe_class_default);
11155 %}
11156 
11157 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11158                              immP needleImm, immL offsetImm, immI_1 needlecntImm,
11159                              iRegIdst tmp1, iRegIdst tmp2,
11160                              flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11161   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11162   effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11163   // Required for EA: check if it is still a type_array.
11164   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11165   ins_cost(150);
11166 
11167   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11168             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11169 
11170   ins_encode %{
11171     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11172     immPOper *needleOper = (immPOper *)$needleImm;
11173     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11174     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11175     jchar chr;
11176 #ifdef VM_LITTLE_ENDIAN
11177     chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11178            ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11179 #else
11180     chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11181            ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11182 #endif
11183     __ string_indexof_char($result$$Register,
11184                            $haystack$$Register, $haycnt$$Register,
11185                            R0, chr,
11186                            $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11187   %}
11188   ins_pipe(pipe_class_compare);
11189 %}
11190 
11191 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11192                              immP needleImm, immL offsetImm, immI_1 needlecntImm,
11193                              iRegIdst tmp1, iRegIdst tmp2,
11194                              flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11195   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11196   effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11197   // Required for EA: check if it is still a type_array.
11198   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11199   ins_cost(150);
11200 
11201   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11202             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11203 
11204   ins_encode %{
11205     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11206     immPOper *needleOper = (immPOper *)$needleImm;
11207     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11208     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11209     jchar chr = (jchar)needle_values->element_value(0).as_byte();
11210     __ string_indexof_char($result$$Register,
11211                            $haystack$$Register, $haycnt$$Register,
11212                            R0, chr,
11213                            $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11214   %}
11215   ins_pipe(pipe_class_compare);
11216 %}
11217 
11218 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11219                               immP needleImm, immL offsetImm, immI_1 needlecntImm,
11220                               iRegIdst tmp1, iRegIdst tmp2,
11221                               flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11222   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11223   effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11224   // Required for EA: check if it is still a type_array.
11225   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11226   ins_cost(150);
11227 
11228   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11229             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11230 
11231   ins_encode %{
11232     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11233     immPOper *needleOper = (immPOper *)$needleImm;
11234     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11235     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11236     jchar chr = (jchar)needle_values->element_value(0).as_byte();
11237     __ string_indexof_char($result$$Register,
11238                            $haystack$$Register, $haycnt$$Register,
11239                            R0, chr,
11240                            $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11241   %}
11242   ins_pipe(pipe_class_compare);
11243 %}
11244 
11245 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11246                         rscratch2RegP needle, immI_1 needlecntImm,
11247                         iRegIdst tmp1, iRegIdst tmp2,
11248                         flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11249   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11250   effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11251   // Required for EA: check if it is still a type_array.
11252   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11253             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11254             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11255   ins_cost(180);
11256 
11257   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11258             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11259   ins_encode %{
11260     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11261     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11262     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11263     guarantee(needle_values, "sanity");
11264     jchar chr;
11265 #ifdef VM_LITTLE_ENDIAN
11266     chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11267            ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11268 #else
11269     chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11270            ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11271 #endif
11272     __ string_indexof_char($result$$Register,
11273                            $haystack$$Register, $haycnt$$Register,
11274                            R0, chr,
11275                            $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11276   %}
11277   ins_pipe(pipe_class_compare);
11278 %}
11279 
11280 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11281                         rscratch2RegP needle, immI_1 needlecntImm,
11282                         iRegIdst tmp1, iRegIdst tmp2,
11283                         flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11284   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11285   effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11286   // Required for EA: check if it is still a type_array.
11287   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11288             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11289             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11290   ins_cost(180);
11291 
11292   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11293             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11294   ins_encode %{
11295     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11296     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11297     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11298     guarantee(needle_values, "sanity");
11299     jchar chr = (jchar)needle_values->element_value(0).as_byte();
11300     __ string_indexof_char($result$$Register,
11301                            $haystack$$Register, $haycnt$$Register,
11302                            R0, chr,
11303                            $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
11304   %}
11305   ins_pipe(pipe_class_compare);
11306 %}
11307 
11308 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11309                          rscratch2RegP needle, immI_1 needlecntImm,
11310                          iRegIdst tmp1, iRegIdst tmp2,
11311                          flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11312   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11313   effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11314   // Required for EA: check if it is still a type_array.
11315   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11316             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11317             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11318   ins_cost(180);
11319 
11320   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11321             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11322   ins_encode %{
11323     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11324     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11325     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11326     guarantee(needle_values, "sanity");
11327     jchar chr = (jchar)needle_values->element_value(0).as_byte();
11328     __ string_indexof_char($result$$Register,
11329                            $haystack$$Register, $haycnt$$Register,
11330                            R0, chr,
11331                            $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11332   %}
11333   ins_pipe(pipe_class_compare);
11334 %}
11335 
11336 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11337                        iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
11338                        flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11339   match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
11340   effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11341   predicate(CompactStrings);
11342   ins_cost(180);
11343 
11344   format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
11345             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11346   ins_encode %{
11347     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11348     __ string_indexof_char($result$$Register,
11349                            $haystack$$Register, $haycnt$$Register,
11350                            $ch$$Register, 0 /* this is not used if the character is already in a register */,
11351                            $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
11352   %}
11353   ins_pipe(pipe_class_compare);
11354 %}
11355 
11356 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11357                        iRegPsrc needle, uimmI15 needlecntImm,
11358                        iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11359                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11360   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11361   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11362          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11363   // Required for EA: check if it is still a type_array.
11364   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
11365             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11366             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11367   ins_cost(250);
11368 
11369   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11370             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11371   ins_encode %{
11372     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11373     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11374     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11375 
11376     __ string_indexof($result$$Register,
11377                       $haystack$$Register, $haycnt$$Register,
11378                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11379                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11380   %}
11381   ins_pipe(pipe_class_compare);
11382 %}
11383 
11384 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11385                        iRegPsrc needle, uimmI15 needlecntImm,
11386                        iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11387                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11388   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11389   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11390          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11391   // Required for EA: check if it is still a type_array.
11392   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
11393             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11394             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11395   ins_cost(250);
11396 
11397   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11398             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11399   ins_encode %{
11400     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11401     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11402     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11403 
11404     __ string_indexof($result$$Register,
11405                       $haystack$$Register, $haycnt$$Register,
11406                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11407                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11408   %}
11409   ins_pipe(pipe_class_compare);
11410 %}
11411 
11412 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11413                         iRegPsrc needle, uimmI15 needlecntImm,
11414                         iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11415                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11416   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11417   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11418          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11419   // Required for EA: check if it is still a type_array.
11420   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
11421             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11422             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11423   ins_cost(250);
11424 
11425   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11426             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11427   ins_encode %{
11428     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11429     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11430     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11431 
11432     __ string_indexof($result$$Register,
11433                       $haystack$$Register, $haycnt$$Register,
11434                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11435                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11436   %}
11437   ins_pipe(pipe_class_compare);
11438 %}
11439 
11440 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11441                    iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11442                    flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11443   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11444   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11445          TEMP_DEF result,
11446          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11447   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
11448   ins_cost(300);
11449 
11450   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11451              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11452   ins_encode %{
11453     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11454     __ string_indexof($result$$Register,
11455                       $haystack$$Register, $haycnt$$Register,
11456                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11457                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
11458   %}
11459   ins_pipe(pipe_class_compare);
11460 %}
11461 
11462 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11463                    iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11464                    flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11465   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11466   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11467          TEMP_DEF result,
11468          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11469   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
11470   ins_cost(300);
11471 
11472   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11473              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11474   ins_encode %{
11475     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11476     __ string_indexof($result$$Register,
11477                       $haystack$$Register, $haycnt$$Register,
11478                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11479                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
11480   %}
11481   ins_pipe(pipe_class_compare);
11482 %}
11483 
11484 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11485                     iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11486                     flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11487   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11488   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11489          TEMP_DEF result,
11490          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11491   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
11492   ins_cost(300);
11493 
11494   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11495              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11496   ins_encode %{
11497     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11498     __ string_indexof($result$$Register,
11499                       $haystack$$Register, $haycnt$$Register,
11500                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11501                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
11502   %}
11503   ins_pipe(pipe_class_compare);
11504 %}
11505 
11506 // char[] to byte[] compression
11507 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11508                          iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11509   match(Set result (StrCompressedCopy src (Binary dst len)));
11510   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11511          USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11512   ins_cost(300);
11513   format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11514   ins_encode %{
11515     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11516     Label Lskip, Ldone;
11517     __ li($result$$Register, 0);
11518     __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11519                           $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone);
11520     __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11521     __ beq(CCR0, Lskip);
11522     __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone);
11523     __ bind(Lskip);
11524     __ mr($result$$Register, $len$$Register);
11525     __ bind(Ldone);
11526   %}
11527   ins_pipe(pipe_class_default);
11528 %}
11529 
11530 // byte[] to char[] inflation
11531 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
11532                         iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11533   match(Set dummy (StrInflatedCopy src (Binary dst len)));
11534   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11535   ins_cost(300);
11536   format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11537   ins_encode %{
11538     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11539     Label Ldone;
11540     __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11541                          $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11542     __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11543     __ beq(CCR0, Ldone);
11544     __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
11545     __ bind(Ldone);
11546   %}
11547   ins_pipe(pipe_class_default);
11548 %}
11549 
11550 // StringCoding.java intrinsics
11551 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
11552                        regCTR ctr, flagsRegCR0 cr0)
11553 %{
11554   match(Set result (HasNegatives ary1 len));
11555   effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
11556   ins_cost(300);
11557   format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
11558   ins_encode %{
11559     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11560     __ has_negatives($ary1$$Register, $len$$Register, $result$$Register,
11561                      $tmp1$$Register, $tmp2$$Register);
11562   %}
11563   ins_pipe(pipe_class_default);
11564 %}
11565 
11566 // encode char[] to byte[] in ISO_8859_1
11567 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
11568                           iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
11569   match(Set result (EncodeISOArray src (Binary dst len)));
11570   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11571          USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
11572   ins_cost(300);
11573   format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11574   ins_encode %{
11575     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11576     Label Lslow, Lfailure1, Lfailure2, Ldone;
11577     __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
11578                           $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1);
11579     __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters.
11580     __ beq(CCR0, Ldone);
11581     __ bind(Lslow);
11582     __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2);
11583     __ li($result$$Register, 0);
11584     __ b(Ldone);
11585 
11586     __ bind(Lfailure1);
11587     __ mr($result$$Register, $len$$Register);
11588     __ mfctr($tmp1$$Register);
11589     __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters.
11590     __ beq(CCR0, Ldone);
11591     __ b(Lslow);
11592 
11593     __ bind(Lfailure2);
11594     __ mfctr($result$$Register); // Remaining characters.
11595 
11596     __ bind(Ldone);
11597     __ subf($result$$Register, $result$$Register, $len$$Register);
11598   %}
11599   ins_pipe(pipe_class_default);
11600 %}
11601 
11602 
11603 // String_IndexOf for needle of length 1.
11604 //
11605 // Match needle into immediate operands: no loadConP node needed. Saves one
11606 // register and two instructions over string_indexOf_imm1Node.
11607 //
11608 // Assumes register result differs from all input registers.
11609 //
11610 // Preserves registers haystack, haycnt
11611 // Kills     registers tmp1, tmp2
11612 // Defines   registers result
11613 //
11614 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11615 //
11616 // Unfortunately this does not match too often. In many situations the AddP is used
11617 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
11618 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11619                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
11620                                   iRegIdst tmp1, iRegIdst tmp2,
11621                                   flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
11622   predicate(SpecialStringIndexOf && !CompactStrings);  // type check implicit by parameter type, See Matcher::match_rule_supported
11623   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11624 
11625   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11626 
11627   ins_cost(150);
11628   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11629             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11630 
11631   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
11632   ins_encode %{
11633     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11634     immPOper *needleOper = (immPOper *)$needleImm;
11635     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11636     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11637     jchar chr;
11638     if (java_lang_String::has_coder_field()) {
11639       // New compact strings byte array strings
11640 #ifdef VM_LITTLE_ENDIAN
11641     chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11642            ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11643 #else
11644     chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11645            ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11646 #endif
11647     } else {
11648       // Old char array strings
11649       chr = needle_values->char_at(0);
11650     }
11651     __ string_indexof_1($result$$Register,
11652                         $haystack$$Register, $haycnt$$Register,
11653                         R0, chr,
11654                         $tmp1$$Register, $tmp2$$Register);
11655   %}
11656   ins_pipe(pipe_class_compare);
11657 %}
11658 
11659 // String_IndexOf for needle of length 1.
11660 //
11661 // Special case requires less registers and emits less instructions.
11662 //
11663 // Assumes register result differs from all input registers.
11664 //
11665 // Preserves registers haystack, haycnt


11676          TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
11677   // Required for EA: check if it is still a type_array.
11678   predicate(SpecialStringIndexOf && !CompactStrings &&
11679             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11680             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11681   ins_cost(180);
11682 
11683   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11684 
11685   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11686             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11687   ins_encode %{
11688     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11689     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11690     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11691     guarantee(needle_values, "sanity");
11692     jchar chr;
11693     if (java_lang_String::has_coder_field()) {
11694       // New compact strings byte array strings
11695 #ifdef VM_LITTLE_ENDIAN
11696     chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
11697            ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
11698 #else
11699     chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
11700            ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
11701 #endif
11702     } else {
11703       // Old char array strings
11704       chr = needle_values->char_at(0);
11705     }
11706     __ string_indexof_1($result$$Register,
11707                         $haystack$$Register, $haycnt$$Register,
11708                         R0, chr,
11709                         $tmp1$$Register, $tmp2$$Register);
11710   %}
11711   ins_pipe(pipe_class_compare);
11712 %}
11713 
11714 // String_IndexOfChar
11715 //
11716 // Assumes register result differs from all input registers.
11717 //
11718 // Preserves registers haystack, haycnt
11719 // Kills     registers tmp1, tmp2
11720 // Defines   registers result


11882 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11883   match(Set dst (MinI src1 src2));
11884   ins_cost(DEFAULT_COST*6);
11885 
11886   expand %{
11887     iRegLdst src1s;
11888     iRegLdst src2s;
11889     iRegLdst diff;
11890     iRegLdst sm;
11891     iRegLdst doz; // difference or zero
11892     convI2L_reg(src1s, src1); // Ensure proper sign extension.
11893     convI2L_reg(src2s, src2); // Ensure proper sign extension.
11894     subL_reg_reg(diff, src2s, src1s);
11895     // Need to consider >=33 bit result, therefore we need signmaskL.
11896     signmask64L_regL(sm, diff);
11897     andL_reg_reg(doz, diff, sm); // <=0
11898     addI_regL_regL(dst, doz, src1s);
11899   %}
11900 %}
11901 
11902 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11903   match(Set dst (MinI src1 src2));
11904   effect(KILL cr0);
11905   predicate(VM_Version::has_isel());
11906   ins_cost(DEFAULT_COST*2);
11907 
11908   ins_encode %{
11909     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11910     __ cmpw(CCR0, $src1$$Register, $src2$$Register);
11911     __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
11912   %}
11913   ins_pipe(pipe_class_default);
11914 %}
11915 
11916 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11917   match(Set dst (MaxI src1 src2));
11918   ins_cost(DEFAULT_COST*6);
11919 
11920   expand %{
11921     iRegLdst src1s;
11922     iRegLdst src2s;
11923     iRegLdst diff;
11924     iRegLdst sm;
11925     iRegLdst doz; // difference or zero
11926     convI2L_reg(src1s, src1); // Ensure proper sign extension.
11927     convI2L_reg(src2s, src2); // Ensure proper sign extension.
11928     subL_reg_reg(diff, src2s, src1s);
11929     // Need to consider >=33 bit result, therefore we need signmaskL.
11930     signmask64L_regL(sm, diff);
11931     andcL_reg_reg(doz, diff, sm); // >=0
11932     addI_regL_regL(dst, doz, src1s);
11933   %}
11934 %}
11935 
11936 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
11937   match(Set dst (MaxI src1 src2));
11938   effect(KILL cr0);
11939   predicate(VM_Version::has_isel());
11940   ins_cost(DEFAULT_COST*2);
11941 
11942   ins_encode %{
11943     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11944     __ cmpw(CCR0, $src1$$Register, $src2$$Register);
11945     __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
11946   %}
11947   ins_pipe(pipe_class_default);
11948 %}
11949 
11950 //---------- Population Count Instructions ------------------------------------
11951 
11952 // Popcnt for Power7.
11953 instruct popCountI(iRegIdst dst, iRegIsrc src) %{
11954   match(Set dst (PopCountI src));
11955   predicate(UsePopCountInstruction && VM_Version::has_popcntw());
11956   ins_cost(DEFAULT_COST);
11957 
11958   format %{ "POPCNTW $dst, $src" %}
11959   size(4);
11960   ins_encode %{
11961     // TODO: PPC port $archOpcode(ppc64Opcode_popcntb);
11962     __ popcntw($dst$$Register, $src$$Register);
11963   %}
11964   ins_pipe(pipe_class_default);
11965 %}
11966 
11967 // Popcnt for Power7.
11968 instruct popCountL(iRegIdst dst, iRegLsrc src) %{
11969   predicate(UsePopCountInstruction && VM_Version::has_popcntw());


< prev index next >