comparison src/cpu/sparc/vm/sparc.ad @ 986:62001a362ce9

6827605: new String intrinsics may prevent EA scalar replacement 6875866: Intrinsic for String.indexOf() is broken on x86 with SSE4.2 Summary: Modify String intrinsic methods to pass char[] pointers instead of string oops. Reviewed-by: never
author kvn
date Mon, 14 Sep 2009 12:14:20 -0700
parents 1fbd5d696bf4
children 1ce3281a8e93
comparison
equal deleted inserted replaced
985:685e959d09ea 986:62001a362ce9
2836 __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp); 2836 __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
2837 // %%%% this mini-loop must not cross a cache boundary! 2837 // %%%% this mini-loop must not cross a cache boundary!
2838 %} 2838 %}
2839 2839
2840 2840
2841 enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{ 2841 enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
2842 Label Ldone, Lloop; 2842 Label Ldone, Lloop;
2843 MacroAssembler _masm(&cbuf); 2843 MacroAssembler _masm(&cbuf);
2844 2844
2845 Register str1_reg = reg_to_register_object($str1$$reg); 2845 Register str1_reg = reg_to_register_object($str1$$reg);
2846 Register str2_reg = reg_to_register_object($str2$$reg); 2846 Register str2_reg = reg_to_register_object($str2$$reg);
2847 Register tmp1_reg = reg_to_register_object($tmp1$$reg); 2847 Register cnt1_reg = reg_to_register_object($cnt1$$reg);
2848 Register tmp2_reg = reg_to_register_object($tmp2$$reg); 2848 Register cnt2_reg = reg_to_register_object($cnt2$$reg);
2849 Register result_reg = reg_to_register_object($result$$reg); 2849 Register result_reg = reg_to_register_object($result$$reg);
2850 2850
2851 // Get the first character position in both strings 2851 assert(result_reg != str1_reg &&
2852 // [8] char array, [12] offset, [16] count 2852 result_reg != str2_reg &&
2853 int value_offset = java_lang_String:: value_offset_in_bytes(); 2853 result_reg != cnt1_reg &&
2854 int offset_offset = java_lang_String::offset_offset_in_bytes(); 2854 result_reg != cnt2_reg ,
2855 int count_offset = java_lang_String:: count_offset_in_bytes(); 2855 "need different registers");
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 2856
2875 // Compute the minimum of the string lengths(str1_reg) and the 2857 // Compute the minimum of the string lengths(str1_reg) and the
2876 // difference of the string lengths (stack) 2858 // 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 2859
2882 // See if the lengths are different, and calculate min in str1_reg. 2860 // 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. 2861 // Stash diff in O7 in case we need it for a tie-breaker.
2884 Label Lskip; 2862 Label Lskip;
2885 // __ subcc(str1_reg, str2_reg, O7); // hoisted 2863 __ subcc(cnt1_reg, cnt2_reg, O7);
2886 __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit 2864 __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
2887 __ br(Assembler::greater, true, Assembler::pt, Lskip); 2865 __ br(Assembler::greater, true, Assembler::pt, Lskip);
2888 // str2 is shorter, so use its count: 2866 // cnt2 is shorter, so use its count:
2889 __ delayed()->sll(str2_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit 2867 __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
2890 __ bind(Lskip); 2868 __ bind(Lskip);
2891 2869
2892 // reallocate str1_reg, str2_reg, result_reg 2870 // reallocate cnt1_reg, cnt2_reg, result_reg
2893 // Note: limit_reg holds the string length pre-scaled by 2 2871 // Note: limit_reg holds the string length pre-scaled by 2
2894 Register limit_reg = str1_reg; 2872 Register limit_reg = cnt1_reg;
2895 Register chr2_reg = str2_reg; 2873 Register chr2_reg = cnt2_reg;
2896 Register chr1_reg = result_reg; 2874 Register chr1_reg = result_reg;
2897 // tmp{12} are the base pointers 2875 // str{12} are the base pointers
2898 2876
2899 // Is the minimum length zero? 2877 // Is the minimum length zero?
2900 __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity 2878 __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
2901 __ br(Assembler::equal, true, Assembler::pn, Ldone); 2879 __ br(Assembler::equal, true, Assembler::pn, Ldone);
2902 __ delayed()->mov(O7, result_reg); // result is difference in lengths 2880 __ delayed()->mov(O7, result_reg); // result is difference in lengths
2903 2881
2904 // Load first characters 2882 // Load first characters
2905 __ lduh(tmp1_reg, 0, chr1_reg); 2883 __ lduh(str1_reg, 0, chr1_reg);
2906 __ lduh(tmp2_reg, 0, chr2_reg); 2884 __ lduh(str2_reg, 0, chr2_reg);
2907 2885
2908 // Compare first characters 2886 // Compare first characters
2909 __ subcc(chr1_reg, chr2_reg, chr1_reg); 2887 __ subcc(chr1_reg, chr2_reg, chr1_reg);
2910 __ br(Assembler::notZero, false, Assembler::pt, Ldone); 2888 __ br(Assembler::notZero, false, Assembler::pt, Ldone);
2911 assert(chr1_reg == result_reg, "result must be pre-placed"); 2889 assert(chr1_reg == result_reg, "result must be pre-placed");
2913 2891
2914 { 2892 {
2915 // Check after comparing first character to see if strings are equivalent 2893 // Check after comparing first character to see if strings are equivalent
2916 Label LSkip2; 2894 Label LSkip2;
2917 // Check if the strings start at same location 2895 // Check if the strings start at same location
2918 __ cmp(tmp1_reg, tmp2_reg); 2896 __ cmp(str1_reg, str2_reg);
2919 __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2); 2897 __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
2920 __ delayed()->nop(); 2898 __ delayed()->nop();
2921 2899
2922 // Check if the length difference is zero (in O7) 2900 // Check if the length difference is zero (in O7)
2923 __ cmp(G0, O7); 2901 __ cmp(G0, O7);
2930 2908
2931 __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg); 2909 __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg);
2932 __ br(Assembler::equal, true, Assembler::pn, Ldone); 2910 __ br(Assembler::equal, true, Assembler::pn, Ldone);
2933 __ delayed()->mov(O7, result_reg); // result is difference in lengths 2911 __ delayed()->mov(O7, result_reg); // result is difference in lengths
2934 2912
2935 // Shift tmp1_reg and tmp2_reg to the end of the arrays, negate limit 2913 // Shift str1_reg and str2_reg to the end of the arrays, negate limit
2936 __ add(tmp1_reg, limit_reg, tmp1_reg); 2914 __ add(str1_reg, limit_reg, str1_reg);
2937 __ add(tmp2_reg, limit_reg, tmp2_reg); 2915 __ add(str2_reg, limit_reg, str2_reg);
2938 __ neg(chr1_reg, limit_reg); // limit = -(limit-2) 2916 __ neg(chr1_reg, limit_reg); // limit = -(limit-2)
2939 2917
2940 // Compare the rest of the characters 2918 // Compare the rest of the characters
2941 __ lduh(tmp1_reg, limit_reg, chr1_reg); 2919 __ lduh(str1_reg, limit_reg, chr1_reg);
2942 __ bind(Lloop); 2920 __ bind(Lloop);
2943 // __ lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted 2921 // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted
2944 __ lduh(tmp2_reg, limit_reg, chr2_reg); 2922 __ lduh(str2_reg, limit_reg, chr2_reg);
2945 __ subcc(chr1_reg, chr2_reg, chr1_reg); 2923 __ subcc(chr1_reg, chr2_reg, chr1_reg);
2946 __ br(Assembler::notZero, false, Assembler::pt, Ldone); 2924 __ br(Assembler::notZero, false, Assembler::pt, Ldone);
2947 assert(chr1_reg == result_reg, "result must be pre-placed"); 2925 assert(chr1_reg == result_reg, "result must be pre-placed");
2948 __ delayed()->inccc(limit_reg, sizeof(jchar)); 2926 __ delayed()->inccc(limit_reg, sizeof(jchar));
2949 // annul LDUH if branch is not taken to prevent access past end of string 2927 // annul LDUH if branch is not taken to prevent access past end of string
2950 __ br(Assembler::notZero, true, Assembler::pt, Lloop); 2928 __ br(Assembler::notZero, true, Assembler::pt, Lloop);
2951 __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted 2929 __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
2952 2930
2953 // If strings are equal up to min length, return the length difference. 2931 // If strings are equal up to min length, return the length difference.
2954 __ mov(O7, result_reg); 2932 __ mov(O7, result_reg);
2955 2933
2956 // Otherwise, return the difference between the first mismatched chars. 2934 // Otherwise, return the difference between the first mismatched chars.
2957 __ bind(Ldone); 2935 __ bind(Ldone);
2958 %} 2936 %}
2959 2937
2960 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{ 2938 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
2961 Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone; 2939 Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
2962 MacroAssembler _masm(&cbuf); 2940 MacroAssembler _masm(&cbuf);
2963 2941
2964 Register str1_reg = reg_to_register_object($str1$$reg); 2942 Register str1_reg = reg_to_register_object($str1$$reg);
2965 Register str2_reg = reg_to_register_object($str2$$reg); 2943 Register str2_reg = reg_to_register_object($str2$$reg);
2966 Register tmp1_reg = reg_to_register_object($tmp1$$reg); 2944 Register cnt_reg = reg_to_register_object($cnt$$reg);
2967 Register tmp2_reg = reg_to_register_object($tmp2$$reg); 2945 Register tmp1_reg = O7;
2968 Register result_reg = reg_to_register_object($result$$reg); 2946 Register result_reg = reg_to_register_object($result$$reg);
2969 2947
2970 // Get the first character position in both strings 2948 assert(result_reg != str1_reg &&
2971 // [8] char array, [12] offset, [16] count 2949 result_reg != str2_reg &&
2972 int value_offset = java_lang_String:: value_offset_in_bytes(); 2950 result_reg != cnt_reg &&
2973 int offset_offset = java_lang_String::offset_offset_in_bytes(); 2951 result_reg != tmp1_reg ,
2974 int count_offset = java_lang_String:: count_offset_in_bytes(); 2952 "need different registers");
2975 2953
2976 // load str1 (jchar*) base address into tmp1_reg 2954 __ cmp(str1_reg, str2_reg); //same char[] ?
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); 2955 __ brx(Assembler::equal, true, Assembler::pn, Ldone);
3003 __ delayed()->add(G0, 1, result_reg); 2956 __ delayed()->add(G0, 1, result_reg);
3004 2957
2958 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
2959 __ delayed()->add(G0, 1, result_reg); // count == 0
2960
3005 //rename registers 2961 //rename registers
3006 Register limit_reg = str1_reg; 2962 Register limit_reg = cnt_reg;
3007 Register chr2_reg = str2_reg;
3008 Register chr1_reg = result_reg; 2963 Register chr1_reg = result_reg;
3009 // tmp{12} are the base pointers 2964 Register chr2_reg = tmp1_reg;
3010 2965
3011 //check for alignment and position the pointers to the ends 2966 //check for alignment and position the pointers to the ends
3012 __ or3(tmp1_reg, tmp2_reg, chr1_reg); 2967 __ or3(str1_reg, str2_reg, chr1_reg);
3013 __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned 2968 __ andcc(chr1_reg, 0x3, chr1_reg);
3014 __ br(Assembler::notZero, false, Assembler::pn, Lchar); 2969 // notZero means at least one not 4-byte aligned.
3015 __ delayed()->nop(); 2970 // We could optimize the case when both arrays are not aligned
3016 2971 // but it is not frequent case and it requires additional checks.
3017 __ bind(Lword); 2972 __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
3018 __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2) 2973 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
3019 __ andn(limit_reg, 0x3, limit_reg); 2974
3020 __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word); 2975 // Compare char[] arrays aligned to 4 bytes.
3021 __ delayed()->nop(); 2976 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
3022 2977 chr1_reg, chr2_reg, Ldone);
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); 2978 __ ba(false,Ldone);
3048 __ delayed()->add(G0, 1, result_reg); 2979 __ delayed()->add(G0, 1, result_reg);
3049 2980
2981 // char by char compare
3050 __ bind(Lchar); 2982 __ bind(Lchar);
3051 __ add(tmp1_reg, limit_reg, tmp1_reg); 2983 __ add(str1_reg, limit_reg, str1_reg);
3052 __ add(tmp2_reg, limit_reg, tmp2_reg); 2984 __ add(str2_reg, limit_reg, str2_reg);
3053 __ neg(limit_reg); //negate count 2985 __ neg(limit_reg); //negate count
3054 2986
3055 __ lduh(tmp1_reg, limit_reg, chr1_reg); 2987 __ lduh(str1_reg, limit_reg, chr1_reg);
2988 // Lchar_loop
3056 __ bind(Lchar_loop); 2989 __ bind(Lchar_loop);
3057 __ lduh(tmp2_reg, limit_reg, chr2_reg); 2990 __ lduh(str2_reg, limit_reg, chr2_reg);
3058 __ cmp(chr1_reg, chr2_reg); 2991 __ cmp(chr1_reg, chr2_reg);
3059 __ br(Assembler::notEqual, true, Assembler::pt, Ldone); 2992 __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3060 __ delayed()->mov(G0, result_reg); //not equal 2993 __ delayed()->mov(G0, result_reg); //not equal
3061 __ inccc(limit_reg, sizeof(jchar)); 2994 __ inccc(limit_reg, sizeof(jchar));
3062 // annul LDUH if branch is not taken to prevent access past end of string 2995 // 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 2996 __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
3064 __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted 2997 __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
3065 2998
3066 __ add(G0, 1, result_reg); //equal 2999 __ add(G0, 1, result_reg); //equal
3067 3000
3068 __ bind(Ldone); 3001 __ bind(Ldone);
3069 %} 3002 %}
3070 3003
3071 enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{ 3004 enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{
3072 Label Lvector, Ldone, Lloop; 3005 Label Lvector, Ldone, Lloop;
3073 MacroAssembler _masm(&cbuf); 3006 MacroAssembler _masm(&cbuf);
3074 3007
3075 Register ary1_reg = reg_to_register_object($ary1$$reg); 3008 Register ary1_reg = reg_to_register_object($ary1$$reg);
3076 Register ary2_reg = reg_to_register_object($ary2$$reg); 3009 Register ary2_reg = reg_to_register_object($ary2$$reg);
3077 Register tmp1_reg = reg_to_register_object($tmp1$$reg); 3010 Register tmp1_reg = reg_to_register_object($tmp1$$reg);
3078 Register tmp2_reg = reg_to_register_object($tmp2$$reg); 3011 Register tmp2_reg = O7;
3079 Register result_reg = reg_to_register_object($result$$reg); 3012 Register result_reg = reg_to_register_object($result$$reg);
3080 3013
3081 int length_offset = arrayOopDesc::length_offset_in_bytes(); 3014 int length_offset = arrayOopDesc::length_offset_in_bytes();
3082 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 3015 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3083 3016
3099 // return false if the two arrays are not equal length 3032 // return false if the two arrays are not equal length
3100 __ cmp(tmp1_reg, tmp2_reg); 3033 __ cmp(tmp1_reg, tmp2_reg);
3101 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); 3034 __ br(Assembler::notEqual, true, Assembler::pn, Ldone);
3102 __ delayed()->mov(G0, result_reg); // not equal 3035 __ delayed()->mov(G0, result_reg); // not equal
3103 3036
3104 __ br_zero(Assembler::zero, true, Assembler::pn, tmp1_reg, Ldone); 3037 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone);
3105 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal 3038 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
3106 3039
3107 // load array addresses 3040 // load array addresses
3108 __ add(ary1_reg, base_offset, ary1_reg); 3041 __ add(ary1_reg, base_offset, ary1_reg);
3109 __ add(ary2_reg, base_offset, ary2_reg); 3042 __ add(ary2_reg, base_offset, ary2_reg);
3110 3043
3111 // renaming registers 3044 // renaming registers
3112 Register chr1_reg = tmp2_reg; // for characters in ary1 3045 Register chr1_reg = result_reg; // for characters in ary1
3113 Register chr2_reg = result_reg; // for characters in ary2 3046 Register chr2_reg = tmp2_reg; // for characters in ary2
3114 Register limit_reg = tmp1_reg; // length 3047 Register limit_reg = tmp1_reg; // length
3115 3048
3116 // set byte count 3049 // set byte count
3117 __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); 3050 __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
3118 __ andcc(limit_reg, 0x2, chr1_reg); //trailing character ? 3051
3119 __ br(Assembler::zero, false, Assembler::pt, Lvector); 3052 // Compare char[] arrays aligned to 4 bytes.
3120 __ delayed()->nop(); 3053 __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
3121 3054 chr1_reg, chr2_reg, Ldone);
3122 //compare the trailing char
3123 __ sub(limit_reg, sizeof(jchar), limit_reg);
3124 __ lduh(ary1_reg, limit_reg, chr1_reg);
3125 __ lduh(ary2_reg, limit_reg, chr2_reg);
3126 __ cmp(chr1_reg, chr2_reg);
3127 __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
3128 __ delayed()->mov(G0, result_reg); // not equal
3129
3130 // only one char ?
3131 __ br_zero(Assembler::zero, true, Assembler::pn, limit_reg, Ldone);
3132 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
3133
3134 __ bind(Lvector);
3135 // Shift ary1_reg and ary2_reg to the end of the arrays, negate limit
3136 __ add(ary1_reg, limit_reg, ary1_reg);
3137 __ add(ary2_reg, limit_reg, ary2_reg);
3138 __ neg(limit_reg, limit_reg);
3139
3140 __ lduw(ary1_reg, limit_reg, chr1_reg);
3141 __ bind(Lloop);
3142 __ lduw(ary2_reg, limit_reg, chr2_reg);
3143 __ cmp(chr1_reg, chr2_reg);
3144 __ br(Assembler::notEqual, false, Assembler::pt, Ldone);
3145 __ delayed()->mov(G0, result_reg); // not equal
3146 __ inccc(limit_reg, 2*sizeof(jchar));
3147 // annul LDUW if branch is not taken to prevent access past end of string
3148 __ br(Assembler::notZero, true, Assembler::pt, Lloop); //annul on taken
3149 __ delayed()->lduw(ary1_reg, limit_reg, chr1_reg); // hoisted
3150
3151 __ add(G0, 1, result_reg); // equals 3055 __ add(G0, 1, result_reg); // equals
3152 3056
3153 __ bind(Ldone); 3057 __ bind(Ldone);
3154 %} 3058 %}
3155 3059
9469 " STX G0,[$base+$temp]\t! delay slot" %} 9373 " STX G0,[$base+$temp]\t! delay slot" %}
9470 ins_encode( enc_Clear_Array(cnt, base, temp) ); 9374 ins_encode( enc_Clear_Array(cnt, base, temp) );
9471 ins_pipe(long_memory_op); 9375 ins_pipe(long_memory_op);
9472 %} 9376 %}
9473 9377
9474 instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, 9378 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
9475 o7RegI tmp3, flagsReg ccr) %{ 9379 o7RegI tmp, flagsReg ccr) %{
9476 match(Set result (StrComp str1 str2)); 9380 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9477 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3); 9381 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
9478 ins_cost(300); 9382 ins_cost(300);
9479 format %{ "String Compare $str1,$str2 -> $result" %} 9383 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %}
9480 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) ); 9384 ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
9481 ins_pipe(long_memory_op); 9385 ins_pipe(long_memory_op);
9482 %} 9386 %}
9483 9387
9484 instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, 9388 instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
9485 o7RegI tmp3, flagsReg ccr) %{ 9389 o7RegI tmp, flagsReg ccr) %{
9486 match(Set result (StrEquals str1 str2)); 9390 match(Set result (StrEquals (Binary str1 str2) cnt));
9487 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3); 9391 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
9488 ins_cost(300); 9392 ins_cost(300);
9489 format %{ "String Equals $str1,$str2 -> $result" %} 9393 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %}
9490 ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) ); 9394 ins_encode( enc_String_Equals(str1, str2, cnt, result) );
9491 ins_pipe(long_memory_op); 9395 ins_pipe(long_memory_op);
9492 %} 9396 %}
9493 9397
9494 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, 9398 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
9495 flagsReg ccr) %{ 9399 o7RegI tmp2, flagsReg ccr) %{
9496 match(Set result (AryEq ary1 ary2)); 9400 match(Set result (AryEq ary1 ary2));
9497 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr); 9401 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
9498 ins_cost(300); 9402 ins_cost(300);
9499 format %{ "Array Equals $ary1,$ary2 -> $result" %} 9403 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %}
9500 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result)); 9404 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result));
9501 ins_pipe(long_memory_op); 9405 ins_pipe(long_memory_op);
9502 %} 9406 %}
9503 9407
9504 9408
9505 //---------- Zeros Count Instructions ------------------------------------------ 9409 //---------- Zeros Count Instructions ------------------------------------------