< prev index next >

src/hotspot/cpu/x86/x86_64.ad

Print this page




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 


< prev index next >