hotspot/src/cpu/sparc/vm/sparc.ad
changeset 33628 09241459a8b8
parent 33129 e0bcbb5015b3
child 34162 16b54851eaf6
equal deleted inserted replaced
33627:c5b7455f846e 33628:09241459a8b8
  2901     FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg)
  2901     FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg)
  2902                                      : reg_to_DoubleFloatRegister_object($src2$$reg);
  2902                                      : reg_to_DoubleFloatRegister_object($src2$$reg);
  2903 
  2903 
  2904     // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1)
  2904     // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1)
  2905     __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
  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   %}
  2906   %}
  3133 
  2907 
  3134   enc_class enc_rethrow() %{
  2908   enc_class enc_rethrow() %{
  3135     cbuf.set_insts_mark();
  2909     cbuf.set_insts_mark();
  3136     Register temp_reg = G3;
  2910     Register temp_reg = G3;
 10273 
 10047 
 10274   %}
 10048   %}
 10275   ins_pipe(long_memory_op);
 10049   ins_pipe(long_memory_op);
 10276 %}
 10050 %}
 10277 
 10051 
 10278 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
 10052 instruct string_compareL(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
 10279                         o7RegI tmp, flagsReg ccr) %{
 10053                          o7RegI tmp, flagsReg ccr) %{
       
 10054   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
 10280   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 10055   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);
 10056   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
 10282   ins_cost(300);
 10057   ins_cost(300);
 10283   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp" %}
 10058   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp" %}
 10284   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
 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   %}                    
 10285   ins_pipe(long_memory_op);
 10065   ins_pipe(long_memory_op);
 10286 %}
 10066 %}
 10287 
 10067 
 10288 instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
 10068 instruct string_compareU(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
 10289                        o7RegI tmp, flagsReg ccr) %{
 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);
 10290   match(Set result (StrEquals (Binary str1 str2) cnt));
 10119   match(Set result (StrEquals (Binary str1 str2) cnt));
 10291   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
 10120   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
 10292   ins_cost(300);
 10121   ins_cost(300);
 10293   format %{ "String Equals $str1,$str2,$cnt -> $result   // KILL $tmp" %}
 10122   format %{ "String Equals byte[] $str1,$str2,$cnt -> $result   // KILL $tmp" %}
 10294   ins_encode( enc_String_Equals(str1, str2, cnt, result) );
 10123   ins_encode %{
       
 10124     __ array_equals(false, $str1$$Register, $str2$$Register,
       
 10125                     $cnt$$Register, $tmp$$Register,
       
 10126                     $result$$Register, true /* byte */);
       
 10127   %}
 10295   ins_pipe(long_memory_op);
 10128   ins_pipe(long_memory_op);
 10296 %}
 10129 %}
 10297 
 10130 
 10298 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
 10131 instruct string_equalsU(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
 10299                       o7RegI tmp2, flagsReg ccr) %{
 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);
 10300   match(Set result (AryEq ary1 ary2));
 10149   match(Set result (AryEq ary1 ary2));
 10301   effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
 10150   effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
 10302   ins_cost(300);
 10151   ins_cost(300);
 10303   format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1,$tmp2" %}
 10152   format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1,$tmp2" %}
 10304   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result));
 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   %}
 10305   ins_pipe(long_memory_op);
 10250   ins_pipe(long_memory_op);
 10306 %}
 10251 %}
 10307 
 10252 
 10308 
 10253 
 10309 //---------- Zeros Count Instructions ------------------------------------------
 10254 //---------- Zeros Count Instructions ------------------------------------------