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