3639 %} 3640 3641 operand rFlagsRegUCF() %{ 3642 constraint(ALLOC_IN_RC(int_flags)); 3643 match(RegFlags); 3644 predicate(false); 3645 3646 format %{ "RFLAGS_U_CF" %} 3647 interface(REG_INTER); 3648 %} 3649 3650 // Float register operands 3651 operand regF() %{ 3652 constraint(ALLOC_IN_RC(float_reg)); 3653 match(RegF); 3654 3655 format %{ %} 3656 interface(REG_INTER); 3657 %} 3658 3659 // Double register operands 3660 operand regD() %{ 3661 constraint(ALLOC_IN_RC(double_reg)); 3662 match(RegD); 3663 3664 format %{ %} 3665 interface(REG_INTER); 3666 %} 3667 3668 // Vectors 3669 operand vecS() %{ 3670 constraint(ALLOC_IN_RC(vectors_reg)); 3671 match(VecS); 3672 3673 format %{ %} 3674 interface(REG_INTER); 3675 %} 3676 3677 operand vecD() %{ 3678 constraint(ALLOC_IN_RC(vectord_reg)); 3679 match(VecD); 3680 3681 format %{ %} 3682 interface(REG_INTER); 3683 %} 3684 3685 operand vecX() %{ 3686 constraint(ALLOC_IN_RC(vectorx_reg)); 3687 match(VecX); 3688 3689 format %{ %} 3690 interface(REG_INTER); 3691 %} 3692 3693 operand vecY() %{ 3694 constraint(ALLOC_IN_RC(vectory_reg)); 3695 match(VecY); 3696 3697 format %{ %} 3698 interface(REG_INTER); 3699 %} 3700 3701 //----------Memory Operands---------------------------------------------------- 3702 // Direct Memory Operand 3703 // operand direct(immP addr) 3704 // %{ 3705 // match(addr); 3706 3707 // format %{ "[$addr]" %} 3708 // interface(MEMORY_INTER) %{ 3709 // base(0xFFFFFFFF); 3710 // index(0x4); 3711 // scale(0x0); 3712 // disp($addr); 3713 // %} 3714 // %} 5270 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5271 ins_encode %{ 5272 __ movl($dst$$Register, $mem$$Address); 5273 %} 5274 ins_pipe(ialu_reg_mem); // XXX 5275 %} 5276 5277 // Load Float 5278 instruct loadF(regF dst, memory mem) 5279 %{ 5280 match(Set dst (LoadF mem)); 5281 5282 ins_cost(145); // XXX 5283 format %{ "movss $dst, $mem\t# float" %} 5284 ins_encode %{ 5285 __ movflt($dst$$XMMRegister, $mem$$Address); 5286 %} 5287 ins_pipe(pipe_slow); // XXX 5288 %} 5289 5290 // Load Double 5291 instruct loadD_partial(regD dst, memory mem) 5292 %{ 5293 predicate(!UseXmmLoadAndClearUpper); 5294 match(Set dst (LoadD mem)); 5295 5296 ins_cost(145); // XXX 5297 format %{ "movlpd $dst, $mem\t# double" %} 5298 ins_encode %{ 5299 __ movdbl($dst$$XMMRegister, $mem$$Address); 5300 %} 5301 ins_pipe(pipe_slow); // XXX 5302 %} 5303 5304 instruct loadD(regD dst, memory mem) 5305 %{ 5306 predicate(UseXmmLoadAndClearUpper); 5307 match(Set dst (LoadD mem)); 5308 5309 ins_cost(145); // XXX 5310 format %{ "movsd $dst, $mem\t# double" %} 5311 ins_encode %{ 5312 __ movdbl($dst$$XMMRegister, $mem$$Address); 5313 %} 5314 ins_pipe(pipe_slow); // XXX 5315 %} 5316 5317 // Load Effective Address 5318 instruct leaP8(rRegP dst, indOffset8 mem) 5319 %{ 5320 match(Set dst mem); 5321 5322 ins_cost(110); // XXX 5323 format %{ "leaq $dst, $mem\t# ptr 8" %} 5324 opcode(0x8D); 5325 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_reg_fat); 5327 %} 5328 5329 instruct leaP32(rRegP dst, indOffset32 mem) 5330 %{ 5331 match(Set dst mem); 5332 5333 ins_cost(110); 5334 format %{ "leaq $dst, $mem\t# ptr 32" %} 5335 opcode(0x8D); 5336 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 10841 $$emit$$"dec rcx\n\t" 10842 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10843 $$emit$$"vmovq xmm0,(rax)\n\t" 10844 $$emit$$"add 0x8,rax\n\t" 10845 $$emit$$"dec rcx\n\t" 10846 $$emit$$"jge L_sloop\n\t" 10847 $$emit$$"# L_end:\n\t" 10848 } else { 10849 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10850 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10851 } 10852 %} 10853 ins_encode %{ 10854 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10855 $tmp$$XMMRegister, true); 10856 %} 10857 ins_pipe(pipe_slow); 10858 %} 10859 10860 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10861 rax_RegI result, regD tmp1, rFlagsReg cr) 10862 %{ 10863 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10864 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10865 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10866 10867 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10868 ins_encode %{ 10869 __ string_compare($str1$$Register, $str2$$Register, 10870 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10871 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10872 %} 10873 ins_pipe( pipe_slow ); 10874 %} 10875 10876 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10877 rax_RegI result, regD tmp1, rFlagsReg cr) 10878 %{ 10879 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10880 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10881 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10882 10883 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10884 ins_encode %{ 10885 __ string_compare($str1$$Register, $str2$$Register, 10886 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10887 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10888 %} 10889 ins_pipe( pipe_slow ); 10890 %} 10891 10892 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10893 rax_RegI result, regD tmp1, rFlagsReg cr) 10894 %{ 10895 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10896 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10897 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10898 10899 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10900 ins_encode %{ 10901 __ string_compare($str1$$Register, $str2$$Register, 10902 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10903 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10904 %} 10905 ins_pipe( pipe_slow ); 10906 %} 10907 10908 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10909 rax_RegI result, regD tmp1, rFlagsReg cr) 10910 %{ 10911 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10912 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10913 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10914 10915 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10916 ins_encode %{ 10917 __ string_compare($str2$$Register, $str1$$Register, 10918 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10919 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10920 %} 10921 ins_pipe( pipe_slow ); 10922 %} 10923 10924 // fast search of substring with known size. 10925 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10926 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10927 %{ 10928 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10929 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10930 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10931 10932 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10933 ins_encode %{ 10934 int icnt2 = (int)$int_cnt2$$constant; 10935 if (icnt2 >= 16) { 10936 // IndexOf for constant substrings with size >= 16 elements 10937 // which don't need to be loaded through stack. 10938 __ string_indexofC8($str1$$Register, $str2$$Register, 10939 $cnt1$$Register, $cnt2$$Register, 10940 icnt2, $result$$Register, 10941 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10942 } else { 10943 // Small strings are loaded through stack if they cross page boundary. 10944 __ string_indexof($str1$$Register, $str2$$Register, 10945 $cnt1$$Register, $cnt2$$Register, 10946 icnt2, $result$$Register, 10947 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10948 } 10949 %} 10950 ins_pipe( pipe_slow ); 10951 %} 10952 10953 // fast search of substring with known size. 10954 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10955 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10956 %{ 10957 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10958 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10959 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10960 10961 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10962 ins_encode %{ 10963 int icnt2 = (int)$int_cnt2$$constant; 10964 if (icnt2 >= 8) { 10965 // IndexOf for constant substrings with size >= 8 elements 10966 // which don't need to be loaded through stack. 10967 __ string_indexofC8($str1$$Register, $str2$$Register, 10968 $cnt1$$Register, $cnt2$$Register, 10969 icnt2, $result$$Register, 10970 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10971 } else { 10972 // Small strings are loaded through stack if they cross page boundary. 10973 __ string_indexof($str1$$Register, $str2$$Register, 10974 $cnt1$$Register, $cnt2$$Register, 10975 icnt2, $result$$Register, 10976 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10977 } 10978 %} 10979 ins_pipe( pipe_slow ); 10980 %} 10981 10982 // fast search of substring with known size. 10983 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10984 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10985 %{ 10986 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10987 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10988 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10989 10990 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10991 ins_encode %{ 10992 int icnt2 = (int)$int_cnt2$$constant; 10993 if (icnt2 >= 8) { 10994 // IndexOf for constant substrings with size >= 8 elements 10995 // which don't need to be loaded through stack. 10996 __ string_indexofC8($str1$$Register, $str2$$Register, 10997 $cnt1$$Register, $cnt2$$Register, 10998 icnt2, $result$$Register, 10999 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11000 } else { 11001 // Small strings are loaded through stack if they cross page boundary. 11002 __ string_indexof($str1$$Register, $str2$$Register, 11003 $cnt1$$Register, $cnt2$$Register, 11004 icnt2, $result$$Register, 11005 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11006 } 11007 %} 11008 ins_pipe( pipe_slow ); 11009 %} 11010 11011 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11012 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11013 %{ 11014 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11015 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11016 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11017 11018 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11019 ins_encode %{ 11020 __ string_indexof($str1$$Register, $str2$$Register, 11021 $cnt1$$Register, $cnt2$$Register, 11022 (-1), $result$$Register, 11023 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11024 %} 11025 ins_pipe( pipe_slow ); 11026 %} 11027 11028 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11029 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11030 %{ 11031 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11032 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11033 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11034 11035 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11036 ins_encode %{ 11037 __ string_indexof($str1$$Register, $str2$$Register, 11038 $cnt1$$Register, $cnt2$$Register, 11039 (-1), $result$$Register, 11040 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11041 %} 11042 ins_pipe( pipe_slow ); 11043 %} 11044 11045 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11046 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11047 %{ 11048 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11049 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11050 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11051 11052 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11053 ins_encode %{ 11054 __ string_indexof($str1$$Register, $str2$$Register, 11055 $cnt1$$Register, $cnt2$$Register, 11056 (-1), $result$$Register, 11057 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11058 %} 11059 ins_pipe( pipe_slow ); 11060 %} 11061 11062 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11063 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11064 %{ 11065 predicate(UseSSE42Intrinsics); 11066 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11067 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11068 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11069 ins_encode %{ 11070 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11071 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11072 %} 11073 ins_pipe( pipe_slow ); 11074 %} 11075 11076 // fast string equals 11077 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11078 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11079 %{ 11080 match(Set result (StrEquals (Binary str1 str2) cnt)); 11081 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11082 11083 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11084 ins_encode %{ 11085 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11086 $cnt$$Register, $result$$Register, $tmp3$$Register, 11087 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11088 %} 11089 ins_pipe( pipe_slow ); 11090 %} 11091 11092 // fast array equals 11093 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11094 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11095 %{ 11096 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11097 match(Set result (AryEq ary1 ary2)); 11098 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11099 11100 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11101 ins_encode %{ 11102 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11103 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11104 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11105 %} 11106 ins_pipe( pipe_slow ); 11107 %} 11108 11109 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11110 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11111 %{ 11112 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11113 match(Set result (AryEq ary1 ary2)); 11114 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11115 11116 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11117 ins_encode %{ 11118 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11119 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11120 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11121 %} 11122 ins_pipe( pipe_slow ); 11123 %} 11124 11125 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11126 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11127 %{ 11128 match(Set result (HasNegatives ary1 len)); 11129 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11130 11131 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11132 ins_encode %{ 11133 __ has_negatives($ary1$$Register, $len$$Register, 11134 $result$$Register, $tmp3$$Register, 11135 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11136 %} 11137 ins_pipe( pipe_slow ); 11138 %} 11139 11140 // fast char[] to byte[] compression 11141 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11142 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11143 match(Set result (StrCompressedCopy src (Binary dst len))); 11144 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11145 11146 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11147 ins_encode %{ 11148 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11149 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11150 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11151 %} 11152 ins_pipe( pipe_slow ); 11153 %} 11154 11155 // fast byte[] to char[] inflation 11156 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11157 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11158 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11159 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11160 11161 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11162 ins_encode %{ 11163 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11164 $tmp1$$XMMRegister, $tmp2$$Register); 11165 %} 11166 ins_pipe( pipe_slow ); 11167 %} 11168 11169 // encode char[] to byte[] in ISO_8859_1 11170 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11171 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11172 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11173 match(Set result (EncodeISOArray src (Binary dst len))); 11174 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11175 11176 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11177 ins_encode %{ 11178 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11179 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11180 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11181 %} 11182 ins_pipe( pipe_slow ); 11183 %} 11184 11185 //----------Overflow Math Instructions----------------------------------------- 11186 11187 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11188 %{ 11189 match(Set cr (OverflowAddI op1 op2)); 11190 effect(DEF cr, USE_KILL op1, USE op2); 11191 | 3639 %} 3640 3641 operand rFlagsRegUCF() %{ 3642 constraint(ALLOC_IN_RC(int_flags)); 3643 match(RegFlags); 3644 predicate(false); 3645 3646 format %{ "RFLAGS_U_CF" %} 3647 interface(REG_INTER); 3648 %} 3649 3650 // Float register operands 3651 operand regF() %{ 3652 constraint(ALLOC_IN_RC(float_reg)); 3653 match(RegF); 3654 3655 format %{ %} 3656 interface(REG_INTER); 3657 %} 3658 3659 // Float register operands 3660 operand vlRegF() %{ 3661 constraint(ALLOC_IN_RC(float_reg_vl)); 3662 match(RegF); 3663 3664 format %{ %} 3665 interface(REG_INTER); 3666 %} 3667 3668 // Double register operands 3669 operand regD() %{ 3670 constraint(ALLOC_IN_RC(double_reg)); 3671 match(RegD); 3672 3673 format %{ %} 3674 interface(REG_INTER); 3675 %} 3676 3677 // Double register operands 3678 operand vlRegD() %{ 3679 constraint(ALLOC_IN_RC(double_reg_vl)); 3680 match(RegD); 3681 3682 format %{ %} 3683 interface(REG_INTER); 3684 %} 3685 3686 // Vectors 3687 operand vecS() %{ 3688 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3689 match(VecS); 3690 3691 format %{ %} 3692 interface(REG_INTER); 3693 %} 3694 3695 // Vectors 3696 operand legVecS() %{ 3697 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3698 match(VecS); 3699 3700 format %{ %} 3701 interface(REG_INTER); 3702 %} 3703 3704 operand vecD() %{ 3705 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3706 match(VecD); 3707 3708 format %{ %} 3709 interface(REG_INTER); 3710 %} 3711 3712 operand legVecD() %{ 3713 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3714 match(VecD); 3715 3716 format %{ %} 3717 interface(REG_INTER); 3718 %} 3719 3720 operand vecX() %{ 3721 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3722 match(VecX); 3723 3724 format %{ %} 3725 interface(REG_INTER); 3726 %} 3727 3728 operand legVecX() %{ 3729 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3730 match(VecX); 3731 3732 format %{ %} 3733 interface(REG_INTER); 3734 %} 3735 3736 operand vecY() %{ 3737 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3738 match(VecY); 3739 3740 format %{ %} 3741 interface(REG_INTER); 3742 %} 3743 3744 operand legVecY() %{ 3745 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3746 match(VecY); 3747 3748 format %{ %} 3749 interface(REG_INTER); 3750 %} 3751 3752 //----------Memory Operands---------------------------------------------------- 3753 // Direct Memory Operand 3754 // operand direct(immP addr) 3755 // %{ 3756 // match(addr); 3757 3758 // format %{ "[$addr]" %} 3759 // interface(MEMORY_INTER) %{ 3760 // base(0xFFFFFFFF); 3761 // index(0x4); 3762 // scale(0x0); 3763 // disp($addr); 3764 // %} 3765 // %} 5321 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5322 ins_encode %{ 5323 __ movl($dst$$Register, $mem$$Address); 5324 %} 5325 ins_pipe(ialu_reg_mem); // XXX 5326 %} 5327 5328 // Load Float 5329 instruct loadF(regF dst, memory mem) 5330 %{ 5331 match(Set dst (LoadF mem)); 5332 5333 ins_cost(145); // XXX 5334 format %{ "movss $dst, $mem\t# float" %} 5335 ins_encode %{ 5336 __ movflt($dst$$XMMRegister, $mem$$Address); 5337 %} 5338 ins_pipe(pipe_slow); // XXX 5339 %} 5340 5341 // Load Float 5342 instruct MoveF2VL(vlRegF dst, regF src) %{ 5343 match(Set dst src); 5344 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5345 ins_encode %{ 5346 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5347 %} 5348 ins_pipe( fpu_reg_reg ); 5349 %} 5350 5351 // Load Float 5352 instruct MoveVL2F(regF dst, vlRegF src) %{ 5353 match(Set dst src); 5354 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5355 ins_encode %{ 5356 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5357 %} 5358 ins_pipe( fpu_reg_reg ); 5359 %} 5360 5361 // Load Double 5362 instruct loadD_partial(regD dst, memory mem) 5363 %{ 5364 predicate(!UseXmmLoadAndClearUpper); 5365 match(Set dst (LoadD mem)); 5366 5367 ins_cost(145); // XXX 5368 format %{ "movlpd $dst, $mem\t# double" %} 5369 ins_encode %{ 5370 __ movdbl($dst$$XMMRegister, $mem$$Address); 5371 %} 5372 ins_pipe(pipe_slow); // XXX 5373 %} 5374 5375 instruct loadD(regD dst, memory mem) 5376 %{ 5377 predicate(UseXmmLoadAndClearUpper); 5378 match(Set dst (LoadD mem)); 5379 5380 ins_cost(145); // XXX 5381 format %{ "movsd $dst, $mem\t# double" %} 5382 ins_encode %{ 5383 __ movdbl($dst$$XMMRegister, $mem$$Address); 5384 %} 5385 ins_pipe(pipe_slow); // XXX 5386 %} 5387 5388 // Load Double 5389 instruct MoveD2VL(vlRegD dst, regD src) %{ 5390 match(Set dst src); 5391 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5392 ins_encode %{ 5393 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5394 %} 5395 ins_pipe( fpu_reg_reg ); 5396 %} 5397 5398 // Load Double 5399 instruct MoveVL2D(regD dst, vlRegD src) %{ 5400 match(Set dst src); 5401 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5402 ins_encode %{ 5403 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5404 %} 5405 ins_pipe( fpu_reg_reg ); 5406 %} 5407 5408 // Load Effective Address 5409 instruct leaP8(rRegP dst, indOffset8 mem) 5410 %{ 5411 match(Set dst mem); 5412 5413 ins_cost(110); // XXX 5414 format %{ "leaq $dst, $mem\t# ptr 8" %} 5415 opcode(0x8D); 5416 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5417 ins_pipe(ialu_reg_reg_fat); 5418 %} 5419 5420 instruct leaP32(rRegP dst, indOffset32 mem) 5421 %{ 5422 match(Set dst mem); 5423 5424 ins_cost(110); 5425 format %{ "leaq $dst, $mem\t# ptr 32" %} 5426 opcode(0x8D); 5427 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 10932 $$emit$$"dec rcx\n\t" 10933 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10934 $$emit$$"vmovq xmm0,(rax)\n\t" 10935 $$emit$$"add 0x8,rax\n\t" 10936 $$emit$$"dec rcx\n\t" 10937 $$emit$$"jge L_sloop\n\t" 10938 $$emit$$"# L_end:\n\t" 10939 } else { 10940 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10941 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10942 } 10943 %} 10944 ins_encode %{ 10945 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10946 $tmp$$XMMRegister, true); 10947 %} 10948 ins_pipe(pipe_slow); 10949 %} 10950 10951 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10952 rax_RegI result, legVecD tmp1, rFlagsReg cr) 10953 %{ 10954 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10955 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10956 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10957 10958 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10959 ins_encode %{ 10960 __ string_compare($str1$$Register, $str2$$Register, 10961 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10962 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10963 %} 10964 ins_pipe( pipe_slow ); 10965 %} 10966 10967 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10968 rax_RegI result, legVecD tmp1, rFlagsReg cr) 10969 %{ 10970 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10971 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10972 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10973 10974 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10975 ins_encode %{ 10976 __ string_compare($str1$$Register, $str2$$Register, 10977 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10978 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10979 %} 10980 ins_pipe( pipe_slow ); 10981 %} 10982 10983 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10984 rax_RegI result, legVecD tmp1, rFlagsReg cr) 10985 %{ 10986 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10987 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10988 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10989 10990 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10991 ins_encode %{ 10992 __ string_compare($str1$$Register, $str2$$Register, 10993 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10994 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10995 %} 10996 ins_pipe( pipe_slow ); 10997 %} 10998 10999 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11000 rax_RegI result, legVecD tmp1, rFlagsReg cr) 11001 %{ 11002 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11003 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11004 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11005 11006 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11007 ins_encode %{ 11008 __ string_compare($str2$$Register, $str1$$Register, 11009 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11010 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11011 %} 11012 ins_pipe( pipe_slow ); 11013 %} 11014 11015 // fast search of substring with known size. 11016 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11017 rbx_RegI result, legVecD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11018 %{ 11019 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11020 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11021 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11022 11023 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11024 ins_encode %{ 11025 int icnt2 = (int)$int_cnt2$$constant; 11026 if (icnt2 >= 16) { 11027 // IndexOf for constant substrings with size >= 16 elements 11028 // which don't need to be loaded through stack. 11029 __ string_indexofC8($str1$$Register, $str2$$Register, 11030 $cnt1$$Register, $cnt2$$Register, 11031 icnt2, $result$$Register, 11032 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11033 } else { 11034 // Small strings are loaded through stack if they cross page boundary. 11035 __ string_indexof($str1$$Register, $str2$$Register, 11036 $cnt1$$Register, $cnt2$$Register, 11037 icnt2, $result$$Register, 11038 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11039 } 11040 %} 11041 ins_pipe( pipe_slow ); 11042 %} 11043 11044 // fast search of substring with known size. 11045 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11046 rbx_RegI result, legVecD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11047 %{ 11048 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11049 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11050 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11051 11052 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11053 ins_encode %{ 11054 int icnt2 = (int)$int_cnt2$$constant; 11055 if (icnt2 >= 8) { 11056 // IndexOf for constant substrings with size >= 8 elements 11057 // which don't need to be loaded through stack. 11058 __ string_indexofC8($str1$$Register, $str2$$Register, 11059 $cnt1$$Register, $cnt2$$Register, 11060 icnt2, $result$$Register, 11061 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11062 } else { 11063 // Small strings are loaded through stack if they cross page boundary. 11064 __ string_indexof($str1$$Register, $str2$$Register, 11065 $cnt1$$Register, $cnt2$$Register, 11066 icnt2, $result$$Register, 11067 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11068 } 11069 %} 11070 ins_pipe( pipe_slow ); 11071 %} 11072 11073 // fast search of substring with known size. 11074 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11075 rbx_RegI result, legVecD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11076 %{ 11077 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11078 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11079 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11080 11081 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11082 ins_encode %{ 11083 int icnt2 = (int)$int_cnt2$$constant; 11084 if (icnt2 >= 8) { 11085 // IndexOf for constant substrings with size >= 8 elements 11086 // which don't need to be loaded through stack. 11087 __ string_indexofC8($str1$$Register, $str2$$Register, 11088 $cnt1$$Register, $cnt2$$Register, 11089 icnt2, $result$$Register, 11090 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11091 } else { 11092 // Small strings are loaded through stack if they cross page boundary. 11093 __ string_indexof($str1$$Register, $str2$$Register, 11094 $cnt1$$Register, $cnt2$$Register, 11095 icnt2, $result$$Register, 11096 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11097 } 11098 %} 11099 ins_pipe( pipe_slow ); 11100 %} 11101 11102 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11103 rbx_RegI result, legVecD vec, rcx_RegI tmp, rFlagsReg cr) 11104 %{ 11105 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11106 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11107 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11108 11109 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11110 ins_encode %{ 11111 __ string_indexof($str1$$Register, $str2$$Register, 11112 $cnt1$$Register, $cnt2$$Register, 11113 (-1), $result$$Register, 11114 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11115 %} 11116 ins_pipe( pipe_slow ); 11117 %} 11118 11119 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11120 rbx_RegI result, legVecD vec, rcx_RegI tmp, rFlagsReg cr) 11121 %{ 11122 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11123 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11124 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11125 11126 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11127 ins_encode %{ 11128 __ string_indexof($str1$$Register, $str2$$Register, 11129 $cnt1$$Register, $cnt2$$Register, 11130 (-1), $result$$Register, 11131 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11132 %} 11133 ins_pipe( pipe_slow ); 11134 %} 11135 11136 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11137 rbx_RegI result, legVecD vec, rcx_RegI tmp, rFlagsReg cr) 11138 %{ 11139 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11140 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11141 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11142 11143 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11144 ins_encode %{ 11145 __ string_indexof($str1$$Register, $str2$$Register, 11146 $cnt1$$Register, $cnt2$$Register, 11147 (-1), $result$$Register, 11148 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11149 %} 11150 ins_pipe( pipe_slow ); 11151 %} 11152 11153 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11154 rbx_RegI result, legVecD vec1, legVecD vec2, legVecD vec3, rcx_RegI tmp, rFlagsReg cr) 11155 %{ 11156 predicate(UseSSE42Intrinsics); 11157 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11158 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11159 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11160 ins_encode %{ 11161 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11162 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11163 %} 11164 ins_pipe( pipe_slow ); 11165 %} 11166 11167 // fast string equals 11168 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11169 legVecD tmp1, legVecD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11170 %{ 11171 match(Set result (StrEquals (Binary str1 str2) cnt)); 11172 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11173 11174 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11175 ins_encode %{ 11176 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11177 $cnt$$Register, $result$$Register, $tmp3$$Register, 11178 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11179 %} 11180 ins_pipe( pipe_slow ); 11181 %} 11182 11183 // fast array equals 11184 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11185 legVecD tmp1, legVecD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11186 %{ 11187 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11188 match(Set result (AryEq ary1 ary2)); 11189 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11190 11191 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11192 ins_encode %{ 11193 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11194 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11195 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11196 %} 11197 ins_pipe( pipe_slow ); 11198 %} 11199 11200 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11201 legVecD tmp1, legVecD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11202 %{ 11203 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11204 match(Set result (AryEq ary1 ary2)); 11205 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11206 11207 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11208 ins_encode %{ 11209 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11210 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11211 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11212 %} 11213 ins_pipe( pipe_slow ); 11214 %} 11215 11216 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11217 legVecD tmp1, legVecD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11218 %{ 11219 match(Set result (HasNegatives ary1 len)); 11220 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11221 11222 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11223 ins_encode %{ 11224 __ has_negatives($ary1$$Register, $len$$Register, 11225 $result$$Register, $tmp3$$Register, 11226 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11227 %} 11228 ins_pipe( pipe_slow ); 11229 %} 11230 11231 // fast char[] to byte[] compression 11232 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecD tmp1, legVecD tmp2, legVecD tmp3, legVecD tmp4, 11233 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11234 match(Set result (StrCompressedCopy src (Binary dst len))); 11235 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11236 11237 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11238 ins_encode %{ 11239 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11240 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11241 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11242 %} 11243 ins_pipe( pipe_slow ); 11244 %} 11245 11246 // fast byte[] to char[] inflation 11247 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11248 legVecD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11249 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11250 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11251 11252 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11253 ins_encode %{ 11254 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11255 $tmp1$$XMMRegister, $tmp2$$Register); 11256 %} 11257 ins_pipe( pipe_slow ); 11258 %} 11259 11260 // encode char[] to byte[] in ISO_8859_1 11261 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11262 legVecD tmp1, legVecD tmp2, legVecD tmp3, legVecD tmp4, 11263 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11264 match(Set result (EncodeISOArray src (Binary dst len))); 11265 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11266 11267 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11268 ins_encode %{ 11269 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11270 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11271 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11272 %} 11273 ins_pipe( pipe_slow ); 11274 %} 11275 11276 //----------Overflow Math Instructions----------------------------------------- 11277 11278 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11279 %{ 11280 match(Set cr (OverflowAddI op1 op2)); 11281 effect(DEF cr, USE_KILL op1, USE op2); 11282 |