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));
|