< prev index next >

src/cpu/sparc/vm/sparc.ad

Print this page




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"


< prev index next >