2888 enc_class enc_iflags_ne_to_boolean( iRegI res ) %{ 2889 Register Rres = reg_to_register_object($res$$reg); 2890 2891 MacroAssembler _masm(&cbuf); 2892 __ mov(1, Rres); 2893 __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); 2894 %} 2895 2896 enc_class floating_cmp ( iRegP dst, regF src1, regF src2 ) %{ 2897 MacroAssembler _masm(&cbuf); 2898 Register Rdst = reg_to_register_object($dst$$reg); 2899 FloatRegister Fsrc1 = $primary ? reg_to_SingleFloatRegister_object($src1$$reg) 2900 : reg_to_DoubleFloatRegister_object($src1$$reg); 2901 FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg) 2902 : reg_to_DoubleFloatRegister_object($src2$$reg); 2903 2904 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) 2905 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); 2906 %} 2907 2908 2909 enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{ 2910 Label Ldone, Lloop; 2911 MacroAssembler _masm(&cbuf); 2912 2913 Register str1_reg = reg_to_register_object($str1$$reg); 2914 Register str2_reg = reg_to_register_object($str2$$reg); 2915 Register cnt1_reg = reg_to_register_object($cnt1$$reg); 2916 Register cnt2_reg = reg_to_register_object($cnt2$$reg); 2917 Register result_reg = reg_to_register_object($result$$reg); 2918 2919 assert(result_reg != str1_reg && 2920 result_reg != str2_reg && 2921 result_reg != cnt1_reg && 2922 result_reg != cnt2_reg , 2923 "need different registers"); 2924 2925 // Compute the minimum of the string lengths(str1_reg) and the 2926 // difference of the string lengths (stack) 2927 2928 // See if the lengths are different, and calculate min in str1_reg. 2929 // Stash diff in O7 in case we need it for a tie-breaker. 2930 Label Lskip; 2931 __ subcc(cnt1_reg, cnt2_reg, O7); 2932 __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit 2933 __ br(Assembler::greater, true, Assembler::pt, Lskip); 2934 // cnt2 is shorter, so use its count: 2935 __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit 2936 __ bind(Lskip); 2937 2938 // reallocate cnt1_reg, cnt2_reg, result_reg 2939 // Note: limit_reg holds the string length pre-scaled by 2 2940 Register limit_reg = cnt1_reg; 2941 Register chr2_reg = cnt2_reg; 2942 Register chr1_reg = result_reg; 2943 // str{12} are the base pointers 2944 2945 // Is the minimum length zero? 2946 __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity 2947 __ br(Assembler::equal, true, Assembler::pn, Ldone); 2948 __ delayed()->mov(O7, result_reg); // result is difference in lengths 2949 2950 // Load first characters 2951 __ lduh(str1_reg, 0, chr1_reg); 2952 __ lduh(str2_reg, 0, chr2_reg); 2953 2954 // Compare first characters 2955 __ subcc(chr1_reg, chr2_reg, chr1_reg); 2956 __ br(Assembler::notZero, false, Assembler::pt, Ldone); 2957 assert(chr1_reg == result_reg, "result must be pre-placed"); 2958 __ delayed()->nop(); 2959 2960 { 2961 // Check after comparing first character to see if strings are equivalent 2962 Label LSkip2; 2963 // Check if the strings start at same location 2964 __ cmp(str1_reg, str2_reg); 2965 __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2); 2966 __ delayed()->nop(); 2967 2968 // Check if the length difference is zero (in O7) 2969 __ cmp(G0, O7); 2970 __ br(Assembler::equal, true, Assembler::pn, Ldone); 2971 __ delayed()->mov(G0, result_reg); // result is zero 2972 2973 // Strings might not be equal 2974 __ bind(LSkip2); 2975 } 2976 2977 // We have no guarantee that on 64 bit the higher half of limit_reg is 0 2978 __ signx(limit_reg); 2979 2980 __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg); 2981 __ br(Assembler::equal, true, Assembler::pn, Ldone); 2982 __ delayed()->mov(O7, result_reg); // result is difference in lengths 2983 2984 // Shift str1_reg and str2_reg to the end of the arrays, negate limit 2985 __ add(str1_reg, limit_reg, str1_reg); 2986 __ add(str2_reg, limit_reg, str2_reg); 2987 __ neg(chr1_reg, limit_reg); // limit = -(limit-2) 2988 2989 // Compare the rest of the characters 2990 __ lduh(str1_reg, limit_reg, chr1_reg); 2991 __ bind(Lloop); 2992 // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted 2993 __ lduh(str2_reg, limit_reg, chr2_reg); 2994 __ subcc(chr1_reg, chr2_reg, chr1_reg); 2995 __ br(Assembler::notZero, false, Assembler::pt, Ldone); 2996 assert(chr1_reg == result_reg, "result must be pre-placed"); 2997 __ delayed()->inccc(limit_reg, sizeof(jchar)); 2998 // annul LDUH if branch is not taken to prevent access past end of string 2999 __ br(Assembler::notZero, true, Assembler::pt, Lloop); 3000 __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted 3001 3002 // If strings are equal up to min length, return the length difference. 3003 __ mov(O7, result_reg); 3004 3005 // Otherwise, return the difference between the first mismatched chars. 3006 __ bind(Ldone); 3007 %} 3008 3009 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{ 3010 Label Lchar, Lchar_loop, Ldone; 3011 MacroAssembler _masm(&cbuf); 3012 3013 Register str1_reg = reg_to_register_object($str1$$reg); 3014 Register str2_reg = reg_to_register_object($str2$$reg); 3015 Register cnt_reg = reg_to_register_object($cnt$$reg); 3016 Register tmp1_reg = O7; 3017 Register result_reg = reg_to_register_object($result$$reg); 3018 3019 assert(result_reg != str1_reg && 3020 result_reg != str2_reg && 3021 result_reg != cnt_reg && 3022 result_reg != tmp1_reg , 3023 "need different registers"); 3024 3025 __ cmp(str1_reg, str2_reg); //same char[] ? 3026 __ brx(Assembler::equal, true, Assembler::pn, Ldone); 3027 __ delayed()->add(G0, 1, result_reg); 3028 3029 __ cmp_zero_and_br(Assembler::zero, cnt_reg, Ldone, true, Assembler::pn); 3030 __ delayed()->add(G0, 1, result_reg); // count == 0 3031 3032 //rename registers 3033 Register limit_reg = cnt_reg; 3034 Register chr1_reg = result_reg; 3035 Register chr2_reg = tmp1_reg; 3036 3037 // We have no guarantee that on 64 bit the higher half of limit_reg is 0 3038 __ signx(limit_reg); 3039 3040 //check for alignment and position the pointers to the ends 3041 __ or3(str1_reg, str2_reg, chr1_reg); 3042 __ andcc(chr1_reg, 0x3, chr1_reg); 3043 // notZero means at least one not 4-byte aligned. 3044 // We could optimize the case when both arrays are not aligned 3045 // but it is not frequent case and it requires additional checks. 3046 __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare 3047 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count 3048 3049 // Compare char[] arrays aligned to 4 bytes. 3050 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg, 3051 chr1_reg, chr2_reg, Ldone); 3052 __ ba(Ldone); 3053 __ delayed()->add(G0, 1, result_reg); 3054 3055 // char by char compare 3056 __ bind(Lchar); 3057 __ add(str1_reg, limit_reg, str1_reg); 3058 __ add(str2_reg, limit_reg, str2_reg); 3059 __ neg(limit_reg); //negate count 3060 3061 __ lduh(str1_reg, limit_reg, chr1_reg); 3062 // Lchar_loop 3063 __ bind(Lchar_loop); 3064 __ lduh(str2_reg, limit_reg, chr2_reg); 3065 __ cmp(chr1_reg, chr2_reg); 3066 __ br(Assembler::notEqual, true, Assembler::pt, Ldone); 3067 __ delayed()->mov(G0, result_reg); //not equal 3068 __ inccc(limit_reg, sizeof(jchar)); 3069 // annul LDUH if branch is not taken to prevent access past end of string 3070 __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); 3071 __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted 3072 3073 __ add(G0, 1, result_reg); //equal 3074 3075 __ bind(Ldone); 3076 %} 3077 3078 enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{ 3079 Label Lvector, Ldone, Lloop; 3080 MacroAssembler _masm(&cbuf); 3081 3082 Register ary1_reg = reg_to_register_object($ary1$$reg); 3083 Register ary2_reg = reg_to_register_object($ary2$$reg); 3084 Register tmp1_reg = reg_to_register_object($tmp1$$reg); 3085 Register tmp2_reg = O7; 3086 Register result_reg = reg_to_register_object($result$$reg); 3087 3088 int length_offset = arrayOopDesc::length_offset_in_bytes(); 3089 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 3090 3091 // return true if the same array 3092 __ cmp(ary1_reg, ary2_reg); 3093 __ brx(Assembler::equal, true, Assembler::pn, Ldone); 3094 __ delayed()->add(G0, 1, result_reg); // equal 3095 3096 __ br_null(ary1_reg, true, Assembler::pn, Ldone); 3097 __ delayed()->mov(G0, result_reg); // not equal 3098 3099 __ br_null(ary2_reg, true, Assembler::pn, Ldone); 3100 __ delayed()->mov(G0, result_reg); // not equal 3101 3102 //load the lengths of arrays 3103 __ ld(Address(ary1_reg, length_offset), tmp1_reg); 3104 __ ld(Address(ary2_reg, length_offset), tmp2_reg); 3105 3106 // return false if the two arrays are not equal length 3107 __ cmp(tmp1_reg, tmp2_reg); 3108 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); 3109 __ delayed()->mov(G0, result_reg); // not equal 3110 3111 __ cmp_zero_and_br(Assembler::zero, tmp1_reg, Ldone, true, Assembler::pn); 3112 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal 3113 3114 // load array addresses 3115 __ add(ary1_reg, base_offset, ary1_reg); 3116 __ add(ary2_reg, base_offset, ary2_reg); 3117 3118 // renaming registers 3119 Register chr1_reg = result_reg; // for characters in ary1 3120 Register chr2_reg = tmp2_reg; // for characters in ary2 3121 Register limit_reg = tmp1_reg; // length 3122 3123 // set byte count 3124 __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); 3125 3126 // Compare char[] arrays aligned to 4 bytes. 3127 __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg, 3128 chr1_reg, chr2_reg, Ldone); 3129 __ add(G0, 1, result_reg); // equals 3130 3131 __ bind(Ldone); 3132 %} 3133 3134 enc_class enc_rethrow() %{ 3135 cbuf.set_insts_mark(); 3136 Register temp_reg = G3; 3137 AddressLiteral rethrow_stub(OptoRuntime::rethrow_stub()); 3138 assert(temp_reg != reg_to_register_object(R_I0_num), "temp must not break oop_reg"); 3139 MacroAssembler _masm(&cbuf); 3140 #ifdef ASSERT 3141 __ save_frame(0); 3142 AddressLiteral last_rethrow_addrlit(&last_rethrow); 3143 __ sethi(last_rethrow_addrlit, L1); 3144 Address addr(L1, last_rethrow_addrlit.low10()); 3145 __ rdpc(L2); 3146 __ inc(L2, 3 * BytesPerInstWord); // skip this & 2 more insns to point at jump_to 3147 __ st_ptr(L2, addr); 3148 __ restore(); 3149 #endif 3150 __ JUMP(rethrow_stub, temp_reg, 0); // sethi;jmp 3151 __ delayed()->nop(); 3152 %} 3153 10258 ins_cost(300); 10259 format %{ "CLEAR [$base, $cnt]\t! ClearArray" %} 10260 10261 ins_encode %{ 10262 10263 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); 10264 Register to = $base$$Register; 10265 Register count = $cnt$$Register; 10266 Register temp = $tmp$$Register; 10267 10268 Label Ldone; 10269 __ nop(); // Separate short branches 10270 // Use BIS for zeroing 10271 __ bis_zeroing(to, count, temp, Ldone); 10272 __ bind(Ldone); 10273 10274 %} 10275 ins_pipe(long_memory_op); 10276 %} 10277 10278 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, 10279 o7RegI tmp, flagsReg ccr) %{ 10280 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10281 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp); 10282 ins_cost(300); 10283 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %} 10284 ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) ); 10285 ins_pipe(long_memory_op); 10286 %} 10287 10288 instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result, 10289 o7RegI tmp, flagsReg ccr) %{ 10290 match(Set result (StrEquals (Binary str1 str2) cnt)); 10291 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr); 10292 ins_cost(300); 10293 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} 10294 ins_encode( enc_String_Equals(str1, str2, cnt, result) ); 10295 ins_pipe(long_memory_op); 10296 %} 10297 10298 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result, 10299 o7RegI tmp2, flagsReg ccr) %{ 10300 match(Set result (AryEq ary1 ary2)); 10301 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr); 10302 ins_cost(300); 10303 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %} 10304 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result)); 10305 ins_pipe(long_memory_op); 10306 %} 10307 10308 10309 //---------- Zeros Count Instructions ------------------------------------------ 10310 10311 instruct countLeadingZerosI(iRegIsafe dst, iRegI src, iRegI tmp, flagsReg cr) %{ 10312 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported 10313 match(Set dst (CountLeadingZerosI src)); 10314 effect(TEMP dst, TEMP tmp, KILL cr); 10315 10316 // x |= (x >> 1); 10317 // x |= (x >> 2); 10318 // x |= (x >> 4); 10319 // x |= (x >> 8); 10320 // x |= (x >> 16); 10321 // return (WORDBITS - popc(x)); 10322 format %{ "SRL $src,1,$tmp\t! count leading zeros (int)\n\t" 10323 "SRL $src,0,$dst\t! 32-bit zero extend\n\t" 10324 "OR $dst,$tmp,$dst\n\t" | 2888 enc_class enc_iflags_ne_to_boolean( iRegI res ) %{ 2889 Register Rres = reg_to_register_object($res$$reg); 2890 2891 MacroAssembler _masm(&cbuf); 2892 __ mov(1, Rres); 2893 __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); 2894 %} 2895 2896 enc_class floating_cmp ( iRegP dst, regF src1, regF src2 ) %{ 2897 MacroAssembler _masm(&cbuf); 2898 Register Rdst = reg_to_register_object($dst$$reg); 2899 FloatRegister Fsrc1 = $primary ? reg_to_SingleFloatRegister_object($src1$$reg) 2900 : reg_to_DoubleFloatRegister_object($src1$$reg); 2901 FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg) 2902 : reg_to_DoubleFloatRegister_object($src2$$reg); 2903 2904 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) 2905 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); 2906 %} 2907 2908 enc_class enc_rethrow() %{ 2909 cbuf.set_insts_mark(); 2910 Register temp_reg = G3; 2911 AddressLiteral rethrow_stub(OptoRuntime::rethrow_stub()); 2912 assert(temp_reg != reg_to_register_object(R_I0_num), "temp must not break oop_reg"); 2913 MacroAssembler _masm(&cbuf); 2914 #ifdef ASSERT 2915 __ save_frame(0); 2916 AddressLiteral last_rethrow_addrlit(&last_rethrow); 2917 __ sethi(last_rethrow_addrlit, L1); 2918 Address addr(L1, last_rethrow_addrlit.low10()); 2919 __ rdpc(L2); 2920 __ inc(L2, 3 * BytesPerInstWord); // skip this & 2 more insns to point at jump_to 2921 __ st_ptr(L2, addr); 2922 __ restore(); 2923 #endif 2924 __ JUMP(rethrow_stub, temp_reg, 0); // sethi;jmp 2925 __ delayed()->nop(); 2926 %} 2927 10032 ins_cost(300); 10033 format %{ "CLEAR [$base, $cnt]\t! ClearArray" %} 10034 10035 ins_encode %{ 10036 10037 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); 10038 Register to = $base$$Register; 10039 Register count = $cnt$$Register; 10040 Register temp = $tmp$$Register; 10041 10042 Label Ldone; 10043 __ nop(); // Separate short branches 10044 // Use BIS for zeroing 10045 __ bis_zeroing(to, count, temp, Ldone); 10046 __ bind(Ldone); 10047 10048 %} 10049 ins_pipe(long_memory_op); 10050 %} 10051 10052 instruct string_compareL(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, 10053 o7RegI tmp, flagsReg ccr) %{ 10054 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10055 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10056 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp); 10057 ins_cost(300); 10058 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %} 10059 ins_encode %{ 10060 __ string_compare($str1$$Register, $str2$$Register, 10061 $cnt1$$Register, $cnt2$$Register, 10062 $tmp$$Register, $tmp$$Register, 10063 $result$$Register, StrIntrinsicNode::LL); 10064 %} 10065 ins_pipe(long_memory_op); 10066 %} 10067 10068 instruct string_compareU(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, 10069 o7RegI tmp, flagsReg ccr) %{ 10070 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10071 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10072 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp); 10073 ins_cost(300); 10074 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %} 10075 ins_encode %{ 10076 __ string_compare($str1$$Register, $str2$$Register, 10077 $cnt1$$Register, $cnt2$$Register, 10078 $tmp$$Register, $tmp$$Register, 10079 $result$$Register, StrIntrinsicNode::UU); 10080 %} 10081 ins_pipe(long_memory_op); 10082 %} 10083 10084 instruct string_compareLU(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, 10085 o7RegI tmp1, g1RegI tmp2, flagsReg ccr) %{ 10086 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10087 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10088 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp1, KILL tmp2); 10089 ins_cost(300); 10090 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1,$tmp2" %} 10091 ins_encode %{ 10092 __ string_compare($str1$$Register, $str2$$Register, 10093 $cnt1$$Register, $cnt2$$Register, 10094 $tmp1$$Register, $tmp2$$Register, 10095 $result$$Register, StrIntrinsicNode::LU); 10096 %} 10097 ins_pipe(long_memory_op); 10098 %} 10099 10100 instruct string_compareUL(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, 10101 o7RegI tmp1, g1RegI tmp2, flagsReg ccr) %{ 10102 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10103 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10104 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp1, KILL tmp2); 10105 ins_cost(300); 10106 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1,$tmp2" %} 10107 ins_encode %{ 10108 __ string_compare($str2$$Register, $str1$$Register, 10109 $cnt2$$Register, $cnt1$$Register, 10110 $tmp1$$Register, $tmp2$$Register, 10111 $result$$Register, StrIntrinsicNode::UL); 10112 %} 10113 ins_pipe(long_memory_op); 10114 %} 10115 10116 instruct string_equalsL(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result, 10117 o7RegI tmp, flagsReg ccr) %{ 10118 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 10119 match(Set result (StrEquals (Binary str1 str2) cnt)); 10120 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr); 10121 ins_cost(300); 10122 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result // KILL $tmp" %} 10123 ins_encode %{ 10124 __ array_equals(false, $str1$$Register, $str2$$Register, 10125 $cnt$$Register, $tmp$$Register, 10126 $result$$Register, true /* byte */); 10127 %} 10128 ins_pipe(long_memory_op); 10129 %} 10130 10131 instruct string_equalsU(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result, 10132 o7RegI tmp, flagsReg ccr) %{ 10133 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 10134 match(Set result (StrEquals (Binary str1 str2) cnt)); 10135 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr); 10136 ins_cost(300); 10137 format %{ "String Equals char[] $str1,$str2,$cnt -> $result // KILL $tmp" %} 10138 ins_encode %{ 10139 __ array_equals(false, $str1$$Register, $str2$$Register, 10140 $cnt$$Register, $tmp$$Register, 10141 $result$$Register, false /* byte */); 10142 %} 10143 ins_pipe(long_memory_op); 10144 %} 10145 10146 instruct array_equalsB(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result, 10147 o7RegI tmp2, flagsReg ccr) %{ 10148 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10149 match(Set result (AryEq ary1 ary2)); 10150 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr); 10151 ins_cost(300); 10152 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %} 10153 ins_encode %{ 10154 __ array_equals(true, $ary1$$Register, $ary2$$Register, 10155 $tmp1$$Register, $tmp2$$Register, 10156 $result$$Register, true /* byte */); 10157 %} 10158 ins_pipe(long_memory_op); 10159 %} 10160 10161 instruct array_equalsC(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result, 10162 o7RegI tmp2, flagsReg ccr) %{ 10163 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 10164 match(Set result (AryEq ary1 ary2)); 10165 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr); 10166 ins_cost(300); 10167 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %} 10168 ins_encode %{ 10169 __ array_equals(true, $ary1$$Register, $ary2$$Register, 10170 $tmp1$$Register, $tmp2$$Register, 10171 $result$$Register, false /* byte */); 10172 %} 10173 ins_pipe(long_memory_op); 10174 %} 10175 10176 // char[] to byte[] compression 10177 instruct string_compress(o0RegP src, o1RegP dst, g3RegI len, notemp_iRegI result, iRegL tmp, flagsReg ccr) %{ 10178 predicate(UseVIS < 3); 10179 match(Set result (StrCompressedCopy src (Binary dst len))); 10180 effect(TEMP result, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr); 10181 ins_cost(300); 10182 format %{ "String Compress $src,$dst,$len -> $result // KILL $tmp" %} 10183 ins_encode %{ 10184 Label Ldone; 10185 __ signx($len$$Register); 10186 __ cmp_zero_and_br(Assembler::zero, $len$$Register, Ldone, false, Assembler::pn); 10187 __ delayed()->mov($len$$Register, $result$$Register); // copy count 10188 __ string_compress($src$$Register, $dst$$Register, $len$$Register, $result$$Register, $tmp$$Register, Ldone); 10189 __ bind(Ldone); 10190 %} 10191 ins_pipe(long_memory_op); 10192 %} 10193 10194 // fast char[] to byte[] compression using VIS instructions 10195 instruct string_compress_fast(o0RegP src, o1RegP dst, g3RegI len, notemp_iRegI result, 10196 iRegL tmp1, iRegL tmp2, iRegL tmp3, iRegL tmp4, 10197 regD ftmp1, regD ftmp2, regD ftmp3, flagsReg ccr) %{ 10198 predicate(UseVIS >= 3); 10199 match(Set result (StrCompressedCopy src (Binary dst len))); 10200 effect(TEMP result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ftmp1, TEMP ftmp2, TEMP ftmp3, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr); 10201 ins_cost(300); 10202 format %{ "String Compress Fast $src,$dst,$len -> $result // KILL $tmp1,$tmp2,$tmp3,$tmp4,$ftmp1,$ftmp2,$ftmp3" %} 10203 ins_encode %{ 10204 Label Ldone; 10205 __ signx($len$$Register); 10206 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $result$$Register, 10207 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, 10208 $ftmp1$$FloatRegister, $ftmp2$$FloatRegister, $ftmp3$$FloatRegister, Ldone); 10209 __ cmp_and_brx_short($len$$Register, 0, Assembler::equal, Assembler::pn, Ldone); 10210 __ string_compress($src$$Register, $dst$$Register, $len$$Register, $result$$Register, $tmp1$$Register, Ldone); 10211 __ bind(Ldone); 10212 %} 10213 ins_pipe(long_memory_op); 10214 %} 10215 10216 // byte[] to char[] inflation 10217 instruct string_inflate(Universe dummy, o0RegP src, o1RegP dst, g3RegI len, 10218 iRegL tmp, flagsReg ccr) %{ 10219 match(Set dummy (StrInflatedCopy src (Binary dst len))); 10220 effect(TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr); 10221 ins_cost(300); 10222 format %{ "String Inflate $src,$dst,$len // KILL $tmp" %} 10223 ins_encode %{ 10224 Label Ldone; 10225 __ signx($len$$Register); 10226 __ cmp_and_brx_short($len$$Register, 0, Assembler::equal, Assembler::pn, Ldone); 10227 __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register, Ldone); 10228 __ bind(Ldone); 10229 %} 10230 ins_pipe(long_memory_op); 10231 %} 10232 10233 // fast byte[] to char[] inflation using VIS instructions 10234 instruct string_inflate_fast(Universe dummy, o0RegP src, o1RegP dst, g3RegI len, 10235 iRegL tmp, regD ftmp1, regD ftmp2, regD ftmp3, regD ftmp4, flagsReg ccr) %{ 10236 predicate(UseVIS >= 3); 10237 match(Set dummy (StrInflatedCopy src (Binary dst len))); 10238 effect(TEMP tmp, TEMP ftmp1, TEMP ftmp2, TEMP ftmp3, TEMP ftmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr); 10239 ins_cost(300); 10240 format %{ "String Inflate Fast $src,$dst,$len // KILL $tmp,$ftmp1,$ftmp2,$ftmp3,$ftmp4" %} 10241 ins_encode %{ 10242 Label Ldone; 10243 __ signx($len$$Register); 10244 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register, 10245 $ftmp1$$FloatRegister, $ftmp2$$FloatRegister, $ftmp3$$FloatRegister, $ftmp4$$FloatRegister, Ldone); 10246 __ cmp_and_brx_short($len$$Register, 0, Assembler::equal, Assembler::pn, Ldone); 10247 __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register, Ldone); 10248 __ bind(Ldone); 10249 %} 10250 ins_pipe(long_memory_op); 10251 %} 10252 10253 10254 //---------- Zeros Count Instructions ------------------------------------------ 10255 10256 instruct countLeadingZerosI(iRegIsafe dst, iRegI src, iRegI tmp, flagsReg cr) %{ 10257 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported 10258 match(Set dst (CountLeadingZerosI src)); 10259 effect(TEMP dst, TEMP tmp, KILL cr); 10260 10261 // x |= (x >> 1); 10262 // x |= (x >> 2); 10263 // x |= (x >> 4); 10264 // x |= (x >> 8); 10265 // x |= (x >> 16); 10266 // return (WORDBITS - popc(x)); 10267 format %{ "SRL $src,1,$tmp\t! count leading zeros (int)\n\t" 10268 "SRL $src,0,$dst\t! 32-bit zero extend\n\t" 10269 "OR $dst,$tmp,$dst\n\t" |