src/cpu/sparc/vm/sparc.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6827605 Sdiff src/cpu/sparc/vm

src/cpu/sparc/vm/sparc.ad

Print this page




2821   // Compiler ensures base is doubleword aligned and cnt is count of doublewords
2822   enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
2823     MacroAssembler _masm(&cbuf);
2824     Register    nof_bytes_arg   = reg_to_register_object($cnt$$reg);
2825     Register    nof_bytes_tmp    = reg_to_register_object($temp$$reg);
2826     Register    base_pointer_arg = reg_to_register_object($base$$reg);
2827 
2828     Label loop;
2829     __ mov(nof_bytes_arg, nof_bytes_tmp);
2830 
2831     // Loop and clear, walking backwards through the array.
2832     // nof_bytes_tmp (if >0) is always the number of bytes to zero
2833     __ bind(loop);
2834     __ deccc(nof_bytes_tmp, 8);
2835     __ br(Assembler::greaterEqual, true, Assembler::pt, loop);
2836     __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
2837     // %%%% this mini-loop must not cross a cache boundary!
2838   %}
2839 
2840 
2841   enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
2842     Label Ldone, Lloop;
2843     MacroAssembler _masm(&cbuf);
2844 
2845     Register   str1_reg = reg_to_register_object($str1$$reg);
2846     Register   str2_reg = reg_to_register_object($str2$$reg);
2847     Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
2848     Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
2849     Register result_reg = reg_to_register_object($result$$reg);
2850 
2851     // Get the first character position in both strings
2852     //         [8] char array, [12] offset, [16] count
2853     int  value_offset = java_lang_String:: value_offset_in_bytes();
2854     int offset_offset = java_lang_String::offset_offset_in_bytes();
2855     int  count_offset = java_lang_String:: count_offset_in_bytes();
2856 
2857     // load str1 (jchar*) base address into tmp1_reg
2858     __ load_heap_oop(str1_reg, value_offset, tmp1_reg);
2859     __ ld(str1_reg, offset_offset, result_reg);
2860     __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
2861     __   ld(str1_reg, count_offset, str1_reg); // hoisted
2862     __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
2863     __   load_heap_oop(str2_reg, value_offset, tmp2_reg); // hoisted
2864     __ add(result_reg, tmp1_reg, tmp1_reg);
2865 
2866     // load str2 (jchar*) base address into tmp2_reg
2867     // __ ld_ptr(str2_reg, value_offset, tmp2_reg); // hoisted
2868     __ ld(str2_reg, offset_offset, result_reg);
2869     __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
2870     __   ld(str2_reg, count_offset, str2_reg); // hoisted
2871     __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
2872     __   subcc(str1_reg, str2_reg, O7); // hoisted
2873     __ add(result_reg, tmp2_reg, tmp2_reg);
2874 
2875     // Compute the minimum of the string lengths(str1_reg) and the
2876     // difference of the string lengths (stack)
2877 
2878     // discard string base pointers, after loading up the lengths
2879     // __ ld(str1_reg, count_offset, str1_reg); // hoisted
2880     // __ ld(str2_reg, count_offset, str2_reg); // hoisted
2881 
2882     // See if the lengths are different, and calculate min in str1_reg.
2883     // Stash diff in O7 in case we need it for a tie-breaker.
2884     Label Lskip;
2885     // __ subcc(str1_reg, str2_reg, O7); // hoisted
2886     __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
2887     __ br(Assembler::greater, true, Assembler::pt, Lskip);
2888     // str2 is shorter, so use its count:
2889     __ delayed()->sll(str2_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
2890     __ bind(Lskip);
2891 
2892     // reallocate str1_reg, str2_reg, result_reg
2893     // Note:  limit_reg holds the string length pre-scaled by 2
2894     Register limit_reg =   str1_reg;
2895     Register  chr2_reg =   str2_reg;
2896     Register  chr1_reg = result_reg;
2897     // tmp{12} are the base pointers
2898 
2899     // Is the minimum length zero?
2900     __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
2901     __ br(Assembler::equal, true, Assembler::pn, Ldone);
2902     __ delayed()->mov(O7, result_reg);  // result is difference in lengths
2903 
2904     // Load first characters
2905     __ lduh(tmp1_reg, 0, chr1_reg);
2906     __ lduh(tmp2_reg, 0, chr2_reg);
2907 
2908     // Compare first characters
2909     __ subcc(chr1_reg, chr2_reg, chr1_reg);
2910     __ br(Assembler::notZero, false, Assembler::pt,  Ldone);
2911     assert(chr1_reg == result_reg, "result must be pre-placed");
2912     __ delayed()->nop();
2913 
2914     {
2915       // Check after comparing first character to see if strings are equivalent
2916       Label LSkip2;
2917       // Check if the strings start at same location
2918       __ cmp(tmp1_reg, tmp2_reg);
2919       __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
2920       __ delayed()->nop();
2921 
2922       // Check if the length difference is zero (in O7)
2923       __ cmp(G0, O7);
2924       __ br(Assembler::equal, true, Assembler::pn, Ldone);
2925       __ delayed()->mov(G0, result_reg);  // result is zero
2926 
2927       // Strings might not be equal
2928       __ bind(LSkip2);
2929     }
2930 
2931     __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg);
2932     __ br(Assembler::equal, true, Assembler::pn, Ldone);
2933     __ delayed()->mov(O7, result_reg);  // result is difference in lengths
2934 
2935     // Shift tmp1_reg and tmp2_reg to the end of the arrays, negate limit
2936     __ add(tmp1_reg, limit_reg, tmp1_reg);
2937     __ add(tmp2_reg, limit_reg, tmp2_reg);
2938     __ neg(chr1_reg, limit_reg);  // limit = -(limit-2)
2939 
2940     // Compare the rest of the characters
2941     __ lduh(tmp1_reg, limit_reg, chr1_reg);
2942     __ bind(Lloop);
2943     // __ lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
2944     __ lduh(tmp2_reg, limit_reg, chr2_reg);
2945     __ subcc(chr1_reg, chr2_reg, chr1_reg);
2946     __ br(Assembler::notZero, false, Assembler::pt, Ldone);
2947     assert(chr1_reg == result_reg, "result must be pre-placed");
2948     __ delayed()->inccc(limit_reg, sizeof(jchar));
2949     // annul LDUH if branch is not taken to prevent access past end of string
2950     __ br(Assembler::notZero, true, Assembler::pt, Lloop);
2951     __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
2952 
2953     // If strings are equal up to min length, return the length difference.
2954     __ mov(O7, result_reg);
2955 
2956     // Otherwise, return the difference between the first mismatched chars.
2957     __ bind(Ldone);
2958   %}
2959 
2960 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
2961     Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
2962     MacroAssembler _masm(&cbuf);
2963 
2964     Register   str1_reg = reg_to_register_object($str1$$reg);
2965     Register   str2_reg = reg_to_register_object($str2$$reg);

2966     Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
2967     Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
2968     Register result_reg = reg_to_register_object($result$$reg);
2969 
2970     // Get the first character position in both strings
2971     //         [8] char array, [12] offset, [16] count
2972     int  value_offset = java_lang_String:: value_offset_in_bytes();
2973     int offset_offset = java_lang_String::offset_offset_in_bytes();
2974     int  count_offset = java_lang_String:: count_offset_in_bytes();
2975 
2976     // load str1 (jchar*) base address into tmp1_reg
2977     __ load_heap_oop(Address(str1_reg, value_offset), tmp1_reg);
2978     __ ld(Address(str1_reg, offset_offset), result_reg);
2979     __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
2980     __    ld(Address(str1_reg, count_offset), str1_reg); // hoisted
2981     __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
2982     __    load_heap_oop(Address(str2_reg, value_offset), tmp2_reg); // hoisted
2983     __ add(result_reg, tmp1_reg, tmp1_reg);
2984 
2985     // load str2 (jchar*) base address into tmp2_reg
2986     // __ ld_ptr(Address(str2_reg, value_offset), tmp2_reg); // hoisted
2987     __ ld(Address(str2_reg, offset_offset), result_reg);
2988     __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
2989     __    ld(Address(str2_reg, count_offset), str2_reg); // hoisted
2990     __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
2991     __   cmp(str1_reg, str2_reg); // hoisted
2992     __ add(result_reg, tmp2_reg, tmp2_reg);
2993 
2994     __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg);
2995     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
2996     __ delayed()->mov(G0, result_reg);    // not equal
2997 
2998     __ br_zero(Assembler::equal, true, Assembler::pn, str1_reg, Ldone);
2999     __ delayed()->add(G0, 1, result_reg); //equals
3000 
3001     __ cmp(tmp1_reg, tmp2_reg); //same string ?
3002     __ brx(Assembler::equal, true, Assembler::pn, Ldone);
3003     __ delayed()->add(G0, 1, result_reg);
3004 
3005     //rename registers
3006     Register limit_reg =   str1_reg;
3007     Register  chr2_reg =   str2_reg;
3008     Register  chr1_reg = result_reg;
3009     // tmp{12} are the base pointers
3010 
3011     //check for alignment and position the pointers to the ends
3012     __ or3(tmp1_reg, tmp2_reg, chr1_reg);
3013     __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
3014     __ br(Assembler::notZero, false, Assembler::pn, Lchar);
3015     __ delayed()->nop();
3016 
3017     __ bind(Lword);
3018     __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2)
3019     __ andn(limit_reg, 0x3, limit_reg);
3020     __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
3021     __ delayed()->nop();
3022 
3023     __ add(tmp1_reg, limit_reg, tmp1_reg);
3024     __ add(tmp2_reg, limit_reg, tmp2_reg);
3025     __ neg(limit_reg);
3026 
3027     __ lduw(tmp1_reg, limit_reg, chr1_reg);

3028     __ bind(Lword_loop);
3029     __ lduw(tmp2_reg, limit_reg, chr2_reg);
3030     __ cmp(chr1_reg, chr2_reg);
3031     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3032     __ delayed()->mov(G0, result_reg);
3033     __ inccc(limit_reg, 2*sizeof(jchar));
3034     // annul LDUW if branch i  s not taken to prevent access past end of string
3035     __ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
3036     __ delayed()->lduw(tmp1_reg, limit_reg, chr1_reg); // hoisted
3037 
3038     __ bind(Lpost_word);
3039     __ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
3040     __ delayed()->add(G0, 1, result_reg);
3041 
3042     __ lduh(tmp1_reg, 0, chr1_reg);
3043     __ lduh(tmp2_reg, 0, chr2_reg);
3044     __ cmp (chr1_reg, chr2_reg);
3045     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3046     __ delayed()->mov(G0, result_reg);
3047     __ ba(false,Ldone);
3048     __ delayed()->add(G0, 1, result_reg);
3049 

3050     __ bind(Lchar);
3051     __ add(tmp1_reg, limit_reg, tmp1_reg);
3052     __ add(tmp2_reg, limit_reg, tmp2_reg);
3053     __ neg(limit_reg); //negate count
3054 
3055     __ lduh(tmp1_reg, limit_reg, chr1_reg);

3056     __ bind(Lchar_loop);
3057     __ lduh(tmp2_reg, limit_reg, chr2_reg);
3058     __ cmp(chr1_reg, chr2_reg);
3059     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3060     __ delayed()->mov(G0, result_reg); //not equal
3061     __ inccc(limit_reg, sizeof(jchar));
3062     // annul LDUH if branch is not taken to prevent access past end of string
3063     __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
3064     __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
3065 
3066     __ add(G0, 1, result_reg);  //equal
3067 
3068     __ bind(Ldone);
3069   %}
3070 
3071 enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
3072     Label Lvector, Ldone, Lloop;
3073     MacroAssembler _masm(&cbuf);
3074 
3075     Register   ary1_reg = reg_to_register_object($ary1$$reg);
3076     Register   ary2_reg = reg_to_register_object($ary2$$reg);
3077     Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
3078     Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
3079     Register result_reg = reg_to_register_object($result$$reg);
3080 
3081     int length_offset  = arrayOopDesc::length_offset_in_bytes();
3082     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3083 
3084     // return true if the same array


9454   size(4*120);       // conservative overestimation ...
9455   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $box" %}
9456   ins_encode( Fast_Unlock(object, box, scratch, scratch2) );
9457   ins_pipe(long_memory_op);
9458 %}
9459 
9460 // Count and Base registers are fixed because the allocator cannot
9461 // kill unknown registers.  The encodings are generic.
9462 instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{
9463   match(Set dummy (ClearArray cnt base));
9464   effect(TEMP temp, KILL ccr);
9465   ins_cost(300);
9466   format %{ "MOV    $cnt,$temp\n"
9467     "loop:   SUBcc  $temp,8,$temp\t! Count down a dword of bytes\n"
9468     "        BRge   loop\t\t! Clearing loop\n"
9469     "        STX    G0,[$base+$temp]\t! delay slot" %}
9470   ins_encode( enc_Clear_Array(cnt, base, temp) );
9471   ins_pipe(long_memory_op);
9472 %}
9473 
9474 instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
9475                         o7RegI tmp3, flagsReg ccr) %{
9476   match(Set result (StrComp str1 str2));
9477   effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
9478   ins_cost(300);
9479   format %{ "String Compare $str1,$str2 -> $result" %}
9480   ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
9481   ins_pipe(long_memory_op);
9482 %}
9483 
9484 instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
9485                        o7RegI tmp3, flagsReg ccr) %{
9486   match(Set result (StrEquals str1 str2));
9487   effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
9488   ins_cost(300);
9489   format %{ "String Equals $str1,$str2 -> $result" %}
9490   ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) );
9491   ins_pipe(long_memory_op);
9492 %}
9493 
9494 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
9495                         flagsReg ccr) %{
9496   match(Set result (AryEq ary1 ary2));
9497   effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
9498   ins_cost(300);
9499   format %{ "Array Equals $ary1,$ary2 -> $result" %}
9500   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
9501   ins_pipe(long_memory_op);
9502 %}
9503 
9504 
9505 //---------- Zeros Count Instructions ------------------------------------------
9506 
9507 instruct countLeadingZerosI(iRegI dst, iRegI src, iRegI tmp, flagsReg cr) %{
9508   predicate(UsePopCountInstruction);  // See Matcher::match_rule_supported
9509   match(Set dst (CountLeadingZerosI src));
9510   effect(TEMP dst, TEMP tmp, KILL cr);




2821   // Compiler ensures base is doubleword aligned and cnt is count of doublewords
2822   enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
2823     MacroAssembler _masm(&cbuf);
2824     Register    nof_bytes_arg   = reg_to_register_object($cnt$$reg);
2825     Register    nof_bytes_tmp    = reg_to_register_object($temp$$reg);
2826     Register    base_pointer_arg = reg_to_register_object($base$$reg);
2827 
2828     Label loop;
2829     __ mov(nof_bytes_arg, nof_bytes_tmp);
2830 
2831     // Loop and clear, walking backwards through the array.
2832     // nof_bytes_tmp (if >0) is always the number of bytes to zero
2833     __ bind(loop);
2834     __ deccc(nof_bytes_tmp, 8);
2835     __ br(Assembler::greaterEqual, true, Assembler::pt, loop);
2836     __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
2837     // %%%% this mini-loop must not cross a cache boundary!
2838   %}
2839 
2840 
2841   enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
2842     Label Ldone, Lloop;
2843     MacroAssembler _masm(&cbuf);
2844 
2845     Register   str1_reg = reg_to_register_object($str1$$reg);
2846     Register   str2_reg = reg_to_register_object($str2$$reg);
2847     Register   cnt1_reg = reg_to_register_object($cnt1$$reg);
2848     Register   cnt2_reg = reg_to_register_object($cnt2$$reg);
2849     Register result_reg = reg_to_register_object($result$$reg);
2850 
2851     assert(result_reg != str1_reg &&
2852            result_reg != str2_reg &&
2853            result_reg != cnt1_reg &&
2854            result_reg != cnt2_reg ,
2855            "need different registers");
2856 


















2857     // Compute the minimum of the string lengths(str1_reg) and the
2858     // difference of the string lengths (stack)
2859 




2860     // See if the lengths are different, and calculate min in str1_reg.
2861     // Stash diff in O7 in case we need it for a tie-breaker.
2862     Label Lskip;
2863     __ subcc(cnt1_reg, cnt2_reg, O7);
2864     __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
2865     __ br(Assembler::greater, true, Assembler::pt, Lskip);
2866     // cnt2 is shorter, so use its count:
2867     __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
2868     __ bind(Lskip);
2869 
2870     // reallocate cnt1_reg, cnt2_reg, result_reg
2871     // Note:  limit_reg holds the string length pre-scaled by 2
2872     Register limit_reg =   cnt1_reg;
2873     Register  chr2_reg =   cnt2_reg;
2874     Register  chr1_reg = result_reg;
2875     // str{12} are the base pointers
2876 
2877     // Is the minimum length zero?
2878     __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
2879     __ br(Assembler::equal, true, Assembler::pn, Ldone);
2880     __ delayed()->mov(O7, result_reg);  // result is difference in lengths
2881 
2882     // Load first characters
2883     __ lduh(str1_reg, 0, chr1_reg);
2884     __ lduh(str2_reg, 0, chr2_reg);
2885 
2886     // Compare first characters
2887     __ subcc(chr1_reg, chr2_reg, chr1_reg);
2888     __ br(Assembler::notZero, false, Assembler::pt,  Ldone);
2889     assert(chr1_reg == result_reg, "result must be pre-placed");
2890     __ delayed()->nop();
2891 
2892     {
2893       // Check after comparing first character to see if strings are equivalent
2894       Label LSkip2;
2895       // Check if the strings start at same location
2896       __ cmp(str1_reg, str2_reg);
2897       __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
2898       __ delayed()->nop();
2899 
2900       // Check if the length difference is zero (in O7)
2901       __ cmp(G0, O7);
2902       __ br(Assembler::equal, true, Assembler::pn, Ldone);
2903       __ delayed()->mov(G0, result_reg);  // result is zero
2904 
2905       // Strings might not be equal
2906       __ bind(LSkip2);
2907     }
2908 
2909     __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg);
2910     __ br(Assembler::equal, true, Assembler::pn, Ldone);
2911     __ delayed()->mov(O7, result_reg);  // result is difference in lengths
2912 
2913     // Shift str1_reg and str2_reg to the end of the arrays, negate limit
2914     __ add(str1_reg, limit_reg, str1_reg);
2915     __ add(str2_reg, limit_reg, str2_reg);
2916     __ neg(chr1_reg, limit_reg);  // limit = -(limit-2)
2917 
2918     // Compare the rest of the characters
2919     __ lduh(str1_reg, limit_reg, chr1_reg);
2920     __ bind(Lloop);
2921     // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted
2922     __ lduh(str2_reg, limit_reg, chr2_reg);
2923     __ subcc(chr1_reg, chr2_reg, chr1_reg);
2924     __ br(Assembler::notZero, false, Assembler::pt, Ldone);
2925     assert(chr1_reg == result_reg, "result must be pre-placed");
2926     __ delayed()->inccc(limit_reg, sizeof(jchar));
2927     // annul LDUH if branch is not taken to prevent access past end of string
2928     __ br(Assembler::notZero, true, Assembler::pt, Lloop);
2929     __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
2930 
2931     // If strings are equal up to min length, return the length difference.
2932     __ mov(O7, result_reg);
2933 
2934     // Otherwise, return the difference between the first mismatched chars.
2935     __ bind(Ldone);
2936   %}
2937 
2938 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, g4RegI tmp1, notemp_iRegI result) %{
2939     Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
2940     MacroAssembler _masm(&cbuf);
2941 
2942     Register   str1_reg = reg_to_register_object($str1$$reg);
2943     Register   str2_reg = reg_to_register_object($str2$$reg);
2944     Register    cnt_reg = reg_to_register_object($cnt$$reg);
2945     Register   tmp1_reg = reg_to_register_object($tmp1$$reg);

2946     Register result_reg = reg_to_register_object($result$$reg);
2947 
2948     assert(result_reg != str1_reg &&
2949            result_reg != str2_reg &&
2950            result_reg !=  cnt_reg &&
2951            result_reg != tmp1_reg ,
2952            "need different registers");
2953 
2954     __ br_zero(Assembler::equal, true, Assembler::pn, cnt_reg, Ldone);
2955     __ delayed()->add(G0, 1, result_reg); // count == 0
2956     __ sll(cnt_reg, exact_log2(sizeof(jchar)), cnt_reg); // bytes count





2957 
2958     __ cmp(str1_reg, str2_reg); //same char[] ?
















2959     __ brx(Assembler::equal, true, Assembler::pn, Ldone);
2960     __ delayed()->add(G0, 1, result_reg);
2961 
2962     //rename registers
2963     Register limit_reg =    cnt_reg;

2964     Register  chr1_reg = result_reg;
2965     Register  chr2_reg =   tmp1_reg;
2966 
2967     //check for alignment and position the pointers to the ends
2968     __ or3(str1_reg, str2_reg, chr1_reg);
2969     __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
2970     __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
2971     __ delayed()->nop();
2972 
2973     // word by word compare
2974     __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2 bytes)
2975     __ andn(limit_reg, 0x3, limit_reg);
2976     __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
2977     __ delayed()->nop();
2978 
2979     __ add(str1_reg, limit_reg, str1_reg);
2980     __ add(str2_reg, limit_reg, str2_reg);
2981     __ neg(limit_reg);
2982 
2983     __ lduw(str1_reg, limit_reg, chr1_reg);
2984     // Lword_loop
2985     __ bind(Lword_loop);
2986     __ lduw(str2_reg, limit_reg, chr2_reg);
2987     __ cmp(chr1_reg, chr2_reg);
2988     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
2989     __ delayed()->mov(G0, result_reg);
2990     __ inccc(limit_reg, 2*sizeof(jchar));
2991     // annul LDUW if branch i  s not taken to prevent access past end of string
2992     __ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
2993     __ delayed()->lduw(str1_reg, limit_reg, chr1_reg); // hoisted
2994 
2995     __ bind(Lpost_word);
2996     __ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
2997     __ delayed()->add(G0, 1, result_reg);
2998 
2999     __ lduh(str1_reg, 0, chr1_reg);
3000     __ lduh(str2_reg, 0, chr2_reg);
3001     __ cmp (chr1_reg, chr2_reg);
3002     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3003     __ delayed()->mov(G0, result_reg);
3004     __ ba(false,Ldone);
3005     __ delayed()->add(G0, 1, result_reg);
3006 
3007     // char by char compare
3008     __ bind(Lchar);
3009     __ add(str1_reg, limit_reg, str1_reg);
3010     __ add(str2_reg, limit_reg, str2_reg);
3011     __ neg(limit_reg); //negate count
3012 
3013     __ lduh(str1_reg, limit_reg, chr1_reg);
3014     // Lchar_loop
3015     __ bind(Lchar_loop);
3016     __ lduh(str2_reg, limit_reg, chr2_reg);
3017     __ cmp(chr1_reg, chr2_reg);
3018     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3019     __ delayed()->mov(G0, result_reg); //not equal
3020     __ inccc(limit_reg, sizeof(jchar));
3021     // annul LDUH if branch is not taken to prevent access past end of string
3022     __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
3023     __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
3024 
3025     __ add(G0, 1, result_reg);  //equal
3026 
3027     __ bind(Ldone);
3028   %}
3029 
3030 enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
3031     Label Lvector, Ldone, Lloop;
3032     MacroAssembler _masm(&cbuf);
3033 
3034     Register   ary1_reg = reg_to_register_object($ary1$$reg);
3035     Register   ary2_reg = reg_to_register_object($ary2$$reg);
3036     Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
3037     Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
3038     Register result_reg = reg_to_register_object($result$$reg);
3039 
3040     int length_offset  = arrayOopDesc::length_offset_in_bytes();
3041     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3042 
3043     // return true if the same array


9413   size(4*120);       // conservative overestimation ...
9414   format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $box" %}
9415   ins_encode( Fast_Unlock(object, box, scratch, scratch2) );
9416   ins_pipe(long_memory_op);
9417 %}
9418 
9419 // Count and Base registers are fixed because the allocator cannot
9420 // kill unknown registers.  The encodings are generic.
9421 instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{
9422   match(Set dummy (ClearArray cnt base));
9423   effect(TEMP temp, KILL ccr);
9424   ins_cost(300);
9425   format %{ "MOV    $cnt,$temp\n"
9426     "loop:   SUBcc  $temp,8,$temp\t! Count down a dword of bytes\n"
9427     "        BRge   loop\t\t! Clearing loop\n"
9428     "        STX    G0,[$base+$temp]\t! delay slot" %}
9429   ins_encode( enc_Clear_Array(cnt, base, temp) );
9430   ins_pipe(long_memory_op);
9431 %}
9432 
9433 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
9434                         o7RegI tmp, flagsReg ccr) %{
9435   match(Set result (StrComp (Binary str1 str2) (Binary cnt1 cnt2)));
9436   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
9437   ins_cost(300);
9438   format %{ "String Compare $str1,$str2,$cnt1,$cnt2 -> $result   // KILL $tmp" %}
9439   ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
9440   ins_pipe(long_memory_op);
9441 %}
9442 
9443 instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, g4RegI tmp1, notemp_iRegI result,
9444                        o7RegI tmp2, flagsReg ccr) %{
9445   match(Set result (StrEquals (Binary str1 str2) cnt));
9446   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp1, KILL tmp2, KILL ccr);
9447   ins_cost(300);
9448   format %{ "String Equals $str1,$str2,$cnt -> $result   // KILL $tmp1, $tmp2" %}
9449   ins_encode( enc_String_Equals(str1, str2, cnt, tmp1, result) );
9450   ins_pipe(long_memory_op);
9451 %}
9452 
9453 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
9454                         flagsReg ccr) %{
9455   match(Set result (AryEq ary1 ary2));
9456   effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
9457   ins_cost(300);
9458   format %{ "Array Equals $ary1,$ary2 -> $result" %}
9459   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
9460   ins_pipe(long_memory_op);
9461 %}
9462 
9463 
9464 //---------- Zeros Count Instructions ------------------------------------------
9465 
9466 instruct countLeadingZerosI(iRegI dst, iRegI src, iRegI tmp, flagsReg cr) %{
9467   predicate(UsePopCountInstruction);  // See Matcher::match_rule_supported
9468   match(Set dst (CountLeadingZerosI src));
9469   effect(TEMP dst, TEMP tmp, KILL cr);


src/cpu/sparc/vm/sparc.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File