< prev index next >

src/cpu/ppc/vm/ppc.ad

Print this page




2037 const bool Matcher::match_rule_supported(int opcode) {
2038   if (!has_match_rule(opcode))
2039     return false;
2040 
2041   switch (opcode) {
2042   case Op_SqrtD:
2043     return VM_Version::has_fsqrt();
2044   case Op_CountLeadingZerosI:
2045   case Op_CountLeadingZerosL:
2046   case Op_CountTrailingZerosI:
2047   case Op_CountTrailingZerosL:
2048     if (!UseCountLeadingZerosInstructionsPPC64)
2049       return false;
2050     break;
2051 
2052   case Op_PopCountI:
2053   case Op_PopCountL:
2054     return (UsePopCountInstruction && VM_Version::has_popcntw());
2055 
2056   case Op_StrComp:
2057     return SpecialStringCompareTo;
2058   case Op_StrEquals:
2059     return SpecialStringEquals;
2060   case Op_StrIndexOf:
2061     return SpecialStringIndexOf;
2062   }
2063 
2064   return true;  // Per default match rules are supported.
2065 }
2066 
2067 const int Matcher::float_pressure(int default_pressure_threshold) {
2068   return default_pressure_threshold;
2069 }
2070 
2071 int Matcher::regnum_to_fpu_offset(int regnum) {
2072   // No user for this method?
2073   Unimplemented();
2074   return 999;
2075 }
2076 
2077 const bool Matcher::convL2FSupported(void) {
2078   // fcfids can do the conversion (>= Power7).
2079   // fcfid + frsp showed rounding problem when result should be 0x3f800001.
2080   return VM_Version::has_fcfids(); // False means that conversion is done by runtime call.
2081 }


11060 
11061 // String_IndexOf for needle of length 1.
11062 //
11063 // Match needle into immediate operands: no loadConP node needed. Saves one
11064 // register and two instructions over string_indexOf_imm1Node.
11065 //
11066 // Assumes register result differs from all input registers.
11067 //
11068 // Preserves registers haystack, haycnt
11069 // Kills     registers tmp1, tmp2
11070 // Defines   registers result
11071 //
11072 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11073 //
11074 // Unfortunately this does not match too often. In many situations the AddP is used
11075 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
11076 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11077                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
11078                                   iRegIdst tmp1, iRegIdst tmp2,
11079                                   flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11080   predicate(SpecialStringIndexOf);  // type check implicit by parameter type, See Matcher::match_rule_supported
11081   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11082 
11083   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
11084 
11085   ins_cost(150);
11086   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11087             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11088 
11089   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
11090   ins_encode %{
11091     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11092     immPOper *needleOper = (immPOper *)$needleImm;
11093     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11094     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11095 
11096     __ string_indexof_1($result$$Register,
11097                         $haystack$$Register, $haycnt$$Register,
11098                         R0, needle_values->char_at(0),
11099                         $tmp1$$Register, $tmp2$$Register);
11100   %}


11103 
11104 // String_IndexOf for needle of length 1.
11105 //
11106 // Special case requires less registers and emits less instructions.
11107 //
11108 // Assumes register result differs from all input registers.
11109 //
11110 // Preserves registers haystack, haycnt
11111 // Kills     registers tmp1, tmp2, needle
11112 // Defines   registers result
11113 //
11114 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11115 instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11116                              rscratch2RegP needle, immI_1 needlecntImm,
11117                              iRegIdst tmp1, iRegIdst tmp2,
11118                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11119   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11120   effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
11121          TEMP tmp1, TEMP tmp2);
11122   // Required for EA: check if it is still a type_array.
11123   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11124             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11125   ins_cost(180);
11126 
11127   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11128 
11129   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11130             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11131   ins_encode %{
11132     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11133     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11134     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11135     guarantee(needle_values, "sanity");
11136     if (needle_values != NULL) {
11137       __ string_indexof_1($result$$Register,
11138                           $haystack$$Register, $haycnt$$Register,
11139                           R0, needle_values->char_at(0),
11140                           $tmp1$$Register, $tmp2$$Register);
11141     } else {
11142       __ string_indexof_1($result$$Register,
11143                           $haystack$$Register, $haycnt$$Register,


11150 
11151 // String_IndexOf.
11152 //
11153 // Length of needle as immediate. This saves instruction loading constant needle
11154 // length.
11155 // @@@ TODO Specify rules for length < 8 or so, and roll out comparison of needle
11156 // completely or do it in vector instruction. This should save registers for
11157 // needlecnt and needle.
11158 //
11159 // Assumes register result differs from all input registers.
11160 // Overwrites haycnt, needlecnt.
11161 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11162 instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11163                             iRegPsrc needle, uimmI15 needlecntImm,
11164                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11165                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11166   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11167   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11168          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
11169   // Required for EA: check if it is still a type_array.
11170   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11171             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11172   ins_cost(250);
11173 
11174   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11175 
11176   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11177             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11178   ins_encode %{
11179     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11180     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11181     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11182 
11183     __ string_indexof($result$$Register,
11184                       $haystack$$Register, $haycnt$$Register,
11185                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11186                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11187   %}
11188   ins_pipe(pipe_class_compare);
11189 %}
11190 
11191 // StrIndexOf node.
11192 //
11193 // Assumes register result differs from all input registers.
11194 // Overwrites haycnt, needlecnt.
11195 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11196 instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11197                         iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11198                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11199   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11200   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11201          TEMP_DEF result,
11202          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
11203   predicate(SpecialStringIndexOf);  // See Matcher::match_rule_supported.
11204   ins_cost(300);
11205 
11206   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11207 
11208   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11209              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11210   ins_encode %{
11211     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11212     __ string_indexof($result$$Register,
11213                       $haystack$$Register, $haycnt$$Register,
11214                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11215                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11216   %}
11217   ins_pipe(pipe_class_compare);
11218 %}
11219 
11220 // String equals with immediate.
11221 instruct string_equals_imm(iRegPsrc str1, iRegPsrc str2, uimmI15 cntImm, iRegIdst result,
11222                            iRegPdst tmp1, iRegPdst tmp2,
11223                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
11224   match(Set result (StrEquals (Binary str1 str2) cntImm));
11225   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
11226          KILL cr0, KILL cr6, KILL ctr);
11227   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
11228   ins_cost(250);
11229 
11230   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11231 
11232   format %{ "String Equals SCL [0..$cntImm]($str1),[0..$cntImm]($str2)"
11233             " -> $result \t// KILL $cr0, $cr6, $ctr, TEMP $result, $tmp1, $tmp2" %}
11234   ins_encode %{
11235     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11236     __ char_arrays_equalsImm($str1$$Register, $str2$$Register, $cntImm$$constant,
11237                              $result$$Register, $tmp1$$Register, $tmp2$$Register);
11238   %}
11239   ins_pipe(pipe_class_compare);
11240 %}
11241 
11242 // String equals.
11243 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11244 instruct string_equals(iRegPsrc str1, iRegPsrc str2, iRegIsrc cnt, iRegIdst result,
11245                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
11246                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11247   match(Set result (StrEquals (Binary str1 str2) cnt));
11248   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11249          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11250   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
11251   ins_cost(300);
11252 
11253   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11254 
11255   format %{ "String Equals [0..$cnt]($str1),[0..$cnt]($str2) -> $result"
11256             " \t// KILL $cr0, $cr1, $cr6, $ctr, TEMP $result, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11257   ins_encode %{
11258     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11259     __ char_arrays_equals($str1$$Register, $str2$$Register, $cnt$$Register, $result$$Register,
11260                           $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11261   %}
11262   ins_pipe(pipe_class_compare);
11263 %}
11264 
11265 // String compare.
11266 // Char[] pointers are passed in.
11267 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11268 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11269                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{

11270   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11271   effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
11272   ins_cost(300);
11273 
11274   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11275 
11276   format %{ "String Compare $str1[0..$cnt1], $str2[0..$cnt2] -> $result"
11277             " \t// TEMP $tmp, $result KILLs $str1, $cnt1, $str2, $cnt2, $cr0, $ctr" %}
11278   ins_encode %{
11279     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11280     __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register,
11281                       $result$$Register, $tmp$$Register);
11282   %}
11283   ins_pipe(pipe_class_compare);
11284 %}
11285 
11286 //---------- Min/Max Instructions ---------------------------------------------
11287 
11288 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11289   match(Set dst (MinI src1 src2));




2037 const bool Matcher::match_rule_supported(int opcode) {
2038   if (!has_match_rule(opcode))
2039     return false;
2040 
2041   switch (opcode) {
2042   case Op_SqrtD:
2043     return VM_Version::has_fsqrt();
2044   case Op_CountLeadingZerosI:
2045   case Op_CountLeadingZerosL:
2046   case Op_CountTrailingZerosI:
2047   case Op_CountTrailingZerosL:
2048     if (!UseCountLeadingZerosInstructionsPPC64)
2049       return false;
2050     break;
2051 
2052   case Op_PopCountI:
2053   case Op_PopCountL:
2054     return (UsePopCountInstruction && VM_Version::has_popcntw());
2055 
2056   case Op_StrComp:
2057     return SpecialStringCompareTo && !CompactStrings;
2058   case Op_StrEquals:
2059     return SpecialStringEquals && !CompactStrings;
2060   case Op_StrIndexOf:
2061     return SpecialStringIndexOf && !CompactStrings;
2062   }
2063 
2064   return true;  // Per default match rules are supported.
2065 }
2066 
2067 const int Matcher::float_pressure(int default_pressure_threshold) {
2068   return default_pressure_threshold;
2069 }
2070 
2071 int Matcher::regnum_to_fpu_offset(int regnum) {
2072   // No user for this method?
2073   Unimplemented();
2074   return 999;
2075 }
2076 
2077 const bool Matcher::convL2FSupported(void) {
2078   // fcfids can do the conversion (>= Power7).
2079   // fcfid + frsp showed rounding problem when result should be 0x3f800001.
2080   return VM_Version::has_fcfids(); // False means that conversion is done by runtime call.
2081 }


11060 
11061 // String_IndexOf for needle of length 1.
11062 //
11063 // Match needle into immediate operands: no loadConP node needed. Saves one
11064 // register and two instructions over string_indexOf_imm1Node.
11065 //
11066 // Assumes register result differs from all input registers.
11067 //
11068 // Preserves registers haystack, haycnt
11069 // Kills     registers tmp1, tmp2
11070 // Defines   registers result
11071 //
11072 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11073 //
11074 // Unfortunately this does not match too often. In many situations the AddP is used
11075 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
11076 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11077                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
11078                                   iRegIdst tmp1, iRegIdst tmp2,
11079                                   flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11080   predicate(SpecialStringIndexOf && !CompactStrings);  // type check implicit by parameter type, See Matcher::match_rule_supported
11081   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
11082 
11083   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
11084 
11085   ins_cost(150);
11086   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
11087             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
11088 
11089   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
11090   ins_encode %{
11091     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11092     immPOper *needleOper = (immPOper *)$needleImm;
11093     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
11094     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
11095 
11096     __ string_indexof_1($result$$Register,
11097                         $haystack$$Register, $haycnt$$Register,
11098                         R0, needle_values->char_at(0),
11099                         $tmp1$$Register, $tmp2$$Register);
11100   %}


11103 
11104 // String_IndexOf for needle of length 1.
11105 //
11106 // Special case requires less registers and emits less instructions.
11107 //
11108 // Assumes register result differs from all input registers.
11109 //
11110 // Preserves registers haystack, haycnt
11111 // Kills     registers tmp1, tmp2, needle
11112 // Defines   registers result
11113 //
11114 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11115 instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
11116                              rscratch2RegP needle, immI_1 needlecntImm,
11117                              iRegIdst tmp1, iRegIdst tmp2,
11118                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
11119   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11120   effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
11121          TEMP tmp1, TEMP tmp2);
11122   // Required for EA: check if it is still a type_array.
11123   predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11124             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11125   ins_cost(180);
11126 
11127   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11128 
11129   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11130             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
11131   ins_encode %{
11132     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11133     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11134     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11135     guarantee(needle_values, "sanity");
11136     if (needle_values != NULL) {
11137       __ string_indexof_1($result$$Register,
11138                           $haystack$$Register, $haycnt$$Register,
11139                           R0, needle_values->char_at(0),
11140                           $tmp1$$Register, $tmp2$$Register);
11141     } else {
11142       __ string_indexof_1($result$$Register,
11143                           $haystack$$Register, $haycnt$$Register,


11150 
11151 // String_IndexOf.
11152 //
11153 // Length of needle as immediate. This saves instruction loading constant needle
11154 // length.
11155 // @@@ TODO Specify rules for length < 8 or so, and roll out comparison of needle
11156 // completely or do it in vector instruction. This should save registers for
11157 // needlecnt and needle.
11158 //
11159 // Assumes register result differs from all input registers.
11160 // Overwrites haycnt, needlecnt.
11161 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11162 instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
11163                             iRegPsrc needle, uimmI15 needlecntImm,
11164                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
11165                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11166   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
11167   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
11168          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
11169   // Required for EA: check if it is still a type_array.
11170   predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
11171             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
11172   ins_cost(250);
11173 
11174   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11175 
11176   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
11177             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
11178   ins_encode %{
11179     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11180     Node *ndl = in(operand_index($needle));  // The node that defines needle.
11181     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
11182 
11183     __ string_indexof($result$$Register,
11184                       $haystack$$Register, $haycnt$$Register,
11185                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
11186                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11187   %}
11188   ins_pipe(pipe_class_compare);
11189 %}
11190 
11191 // StrIndexOf node.
11192 //
11193 // Assumes register result differs from all input registers.
11194 // Overwrites haycnt, needlecnt.
11195 // Use dst register classes if register gets killed, as it is the case for tmp registers!
11196 instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
11197                         iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
11198                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
11199   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
11200   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
11201          TEMP_DEF result,
11202          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
11203   predicate(SpecialStringIndexOf && !CompactStrings);  // See Matcher::match_rule_supported.
11204   ins_cost(300);
11205 
11206   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11207 
11208   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
11209              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
11210   ins_encode %{
11211     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11212     __ string_indexof($result$$Register,
11213                       $haystack$$Register, $haycnt$$Register,
11214                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
11215                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
11216   %}
11217   ins_pipe(pipe_class_compare);
11218 %}
11219 
11220 // String equals with immediate.
11221 instruct string_equals_imm(iRegPsrc str1, iRegPsrc str2, uimmI15 cntImm, iRegIdst result,
11222                            iRegPdst tmp1, iRegPdst tmp2,
11223                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
11224   match(Set result (StrEquals (Binary str1 str2) cntImm));
11225   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
11226          KILL cr0, KILL cr6, KILL ctr);
11227   predicate(SpecialStringEquals && !CompactStrings);  // See Matcher::match_rule_supported.
11228   ins_cost(250);
11229 
11230   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11231 
11232   format %{ "String Equals SCL [0..$cntImm]($str1),[0..$cntImm]($str2)"
11233             " -> $result \t// KILL $cr0, $cr6, $ctr, TEMP $result, $tmp1, $tmp2" %}
11234   ins_encode %{
11235     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11236     __ char_arrays_equalsImm($str1$$Register, $str2$$Register, $cntImm$$constant,
11237                              $result$$Register, $tmp1$$Register, $tmp2$$Register);
11238   %}
11239   ins_pipe(pipe_class_compare);
11240 %}
11241 
11242 // String equals.
11243 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11244 instruct string_equals(iRegPsrc str1, iRegPsrc str2, iRegIsrc cnt, iRegIdst result,
11245                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
11246                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
11247   match(Set result (StrEquals (Binary str1 str2) cnt));
11248   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
11249          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
11250   predicate(SpecialStringEquals && !CompactStrings);  // See Matcher::match_rule_supported.
11251   ins_cost(300);
11252 
11253   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11254 
11255   format %{ "String Equals [0..$cnt]($str1),[0..$cnt]($str2) -> $result"
11256             " \t// KILL $cr0, $cr1, $cr6, $ctr, TEMP $result, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
11257   ins_encode %{
11258     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11259     __ char_arrays_equals($str1$$Register, $str2$$Register, $cnt$$Register, $result$$Register,
11260                           $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
11261   %}
11262   ins_pipe(pipe_class_compare);
11263 %}
11264 
11265 // String compare.
11266 // Char[] pointers are passed in.
11267 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
11268 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11269                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
11270   predicate(!CompactStrings);
11271   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11272   effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
11273   ins_cost(300);
11274 
11275   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11276 
11277   format %{ "String Compare $str1[0..$cnt1], $str2[0..$cnt2] -> $result"
11278             " \t// TEMP $tmp, $result KILLs $str1, $cnt1, $str2, $cnt2, $cr0, $ctr" %}
11279   ins_encode %{
11280     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11281     __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register,
11282                       $result$$Register, $tmp$$Register);
11283   %}
11284   ins_pipe(pipe_class_compare);
11285 %}
11286 
11287 //---------- Min/Max Instructions ---------------------------------------------
11288 
11289 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
11290   match(Set dst (MinI src1 src2));


< prev index next >