hotspot/src/cpu/x86/vm/x86_64.ad
changeset 33628 09241459a8b8
parent 33465 6063f28a6efb
child 34162 16b54851eaf6
equal deleted inserted replaced
33627:c5b7455f846e 33628:09241459a8b8
 10445     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
 10445     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
 10446   %}
 10446   %}
 10447   ins_pipe( pipe_slow );
 10447   ins_pipe( pipe_slow );
 10448 %}
 10448 %}
 10449 
 10449 
 10450 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
 10450 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
 10451                         rax_RegI result, regD tmp1, rFlagsReg cr)
 10451                          rax_RegI result, regD tmp1, rFlagsReg cr)
 10452 %{
 10452 %{
       
 10453   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
 10453   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 10454   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 10454   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
 10455   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
 10455 
 10456 
 10456   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
 10457   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
 10457   ins_encode %{
 10458   ins_encode %{
 10458     __ string_compare($str1$$Register, $str2$$Register,
 10459     __ string_compare($str1$$Register, $str2$$Register,
 10459                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
 10460                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
 10460                       $tmp1$$XMMRegister);
 10461                       $tmp1$$XMMRegister, StrIntrinsicNode::LL);
 10461   %}
 10462   %}
 10462   ins_pipe( pipe_slow );
 10463   ins_pipe( pipe_slow );
 10463 %}
 10464 %}
 10464 
 10465 
       
 10466 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
       
 10467                          rax_RegI result, regD tmp1, rFlagsReg cr)
       
 10468 %{
       
 10469   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
       
 10470   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
       
 10471   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
       
 10472 
       
 10473   format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
       
 10474   ins_encode %{
       
 10475     __ string_compare($str1$$Register, $str2$$Register,
       
 10476                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
       
 10477                       $tmp1$$XMMRegister, StrIntrinsicNode::UU);
       
 10478   %}
       
 10479   ins_pipe( pipe_slow );
       
 10480 %}
       
 10481 
       
 10482 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
       
 10483                           rax_RegI result, regD tmp1, rFlagsReg cr)
       
 10484 %{
       
 10485   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
       
 10486   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
       
 10487   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
       
 10488 
       
 10489   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
       
 10490   ins_encode %{
       
 10491     __ string_compare($str1$$Register, $str2$$Register,
       
 10492                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
       
 10493                       $tmp1$$XMMRegister, StrIntrinsicNode::LU);
       
 10494   %}
       
 10495   ins_pipe( pipe_slow );
       
 10496 %}
       
 10497 
       
 10498 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2,
       
 10499                           rax_RegI result, regD tmp1, rFlagsReg cr)
       
 10500 %{
       
 10501   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
       
 10502   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
       
 10503   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
       
 10504 
       
 10505   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
       
 10506   ins_encode %{
       
 10507     __ string_compare($str2$$Register, $str1$$Register,
       
 10508                       $cnt2$$Register, $cnt1$$Register, $result$$Register,
       
 10509                       $tmp1$$XMMRegister, StrIntrinsicNode::UL);
       
 10510   %}
       
 10511   ins_pipe( pipe_slow );
       
 10512 %}
       
 10513 
 10465 // fast search of substring with known size.
 10514 // fast search of substring with known size.
 10466 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
 10515 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
 10467                             rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
 10516                              rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
 10468 %{
 10517 %{
 10469   predicate(UseSSE42Intrinsics);
 10518   predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
 10470   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
 10519   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
 10471   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
 10520   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
 10472 
 10521 
 10473   format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
 10522   format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
       
 10523   ins_encode %{
       
 10524     int icnt2 = (int)$int_cnt2$$constant;
       
 10525     if (icnt2 >= 16) {
       
 10526       // IndexOf for constant substrings with size >= 16 elements
       
 10527       // which don't need to be loaded through stack.
       
 10528       __ string_indexofC8($str1$$Register, $str2$$Register,
       
 10529                           $cnt1$$Register, $cnt2$$Register,
       
 10530                           icnt2, $result$$Register,
       
 10531                           $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
       
 10532     } else {
       
 10533       // Small strings are loaded through stack if they cross page boundary.
       
 10534       __ string_indexof($str1$$Register, $str2$$Register,
       
 10535                         $cnt1$$Register, $cnt2$$Register,
       
 10536                         icnt2, $result$$Register,
       
 10537                         $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
       
 10538     }
       
 10539   %}
       
 10540   ins_pipe( pipe_slow );
       
 10541 %}
       
 10542 
       
 10543 // fast search of substring with known size.
       
 10544 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
       
 10545                              rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
       
 10546 %{
       
 10547   predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
       
 10548   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
       
 10549   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
       
 10550 
       
 10551   format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
 10474   ins_encode %{
 10552   ins_encode %{
 10475     int icnt2 = (int)$int_cnt2$$constant;
 10553     int icnt2 = (int)$int_cnt2$$constant;
 10476     if (icnt2 >= 8) {
 10554     if (icnt2 >= 8) {
 10477       // IndexOf for constant substrings with size >= 8 elements
 10555       // IndexOf for constant substrings with size >= 8 elements
 10478       // which don't need to be loaded through stack.
 10556       // which don't need to be loaded through stack.
 10479       __ string_indexofC8($str1$$Register, $str2$$Register,
 10557       __ string_indexofC8($str1$$Register, $str2$$Register,
 10480                           $cnt1$$Register, $cnt2$$Register,
 10558                           $cnt1$$Register, $cnt2$$Register,
 10481                           icnt2, $result$$Register,
 10559                           icnt2, $result$$Register,
 10482                           $vec$$XMMRegister, $tmp$$Register);
 10560                           $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
 10483     } else {
 10561     } else {
 10484       // Small strings are loaded through stack if they cross page boundary.
 10562       // Small strings are loaded through stack if they cross page boundary.
 10485       __ string_indexof($str1$$Register, $str2$$Register,
 10563       __ string_indexof($str1$$Register, $str2$$Register,
 10486                         $cnt1$$Register, $cnt2$$Register,
 10564                         $cnt1$$Register, $cnt2$$Register,
 10487                         icnt2, $result$$Register,
 10565                         icnt2, $result$$Register,
 10488                         $vec$$XMMRegister, $tmp$$Register);
 10566                         $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
 10489     }
 10567     }
 10490   %}
 10568   %}
 10491   ins_pipe( pipe_slow );
 10569   ins_pipe( pipe_slow );
 10492 %}
 10570 %}
 10493 
 10571 
 10494 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
 10572 // fast search of substring with known size.
 10495                         rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
 10573 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
 10496 %{
 10574                              rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
 10497   predicate(UseSSE42Intrinsics);
 10575 %{
       
 10576   predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
       
 10577   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
       
 10578   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
       
 10579 
       
 10580   format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
       
 10581   ins_encode %{
       
 10582     int icnt2 = (int)$int_cnt2$$constant;
       
 10583     if (icnt2 >= 8) {
       
 10584       // IndexOf for constant substrings with size >= 8 elements
       
 10585       // which don't need to be loaded through stack.
       
 10586       __ string_indexofC8($str1$$Register, $str2$$Register,
       
 10587                           $cnt1$$Register, $cnt2$$Register,
       
 10588                           icnt2, $result$$Register,
       
 10589                           $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
       
 10590     } else {
       
 10591       // Small strings are loaded through stack if they cross page boundary.
       
 10592       __ string_indexof($str1$$Register, $str2$$Register,
       
 10593                         $cnt1$$Register, $cnt2$$Register,
       
 10594                         icnt2, $result$$Register,
       
 10595                         $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
       
 10596     }
       
 10597   %}
       
 10598   ins_pipe( pipe_slow );
       
 10599 %}
       
 10600 
       
 10601 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
       
 10602                          rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
       
 10603 %{
       
 10604   predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
 10498   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
 10605   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
 10499   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
 10606   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
 10500 
 10607 
 10501   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
 10608   format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
 10502   ins_encode %{
 10609   ins_encode %{
 10503     __ string_indexof($str1$$Register, $str2$$Register,
 10610     __ string_indexof($str1$$Register, $str2$$Register,
 10504                       $cnt1$$Register, $cnt2$$Register,
 10611                       $cnt1$$Register, $cnt2$$Register,
 10505                       (-1), $result$$Register,
 10612                       (-1), $result$$Register,
 10506                       $vec$$XMMRegister, $tmp$$Register);
 10613                       $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
       
 10614   %}
       
 10615   ins_pipe( pipe_slow );
       
 10616 %}
       
 10617 
       
 10618 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
       
 10619                          rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
       
 10620 %{
       
 10621   predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
       
 10622   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
       
 10623   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
       
 10624 
       
 10625   format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
       
 10626   ins_encode %{
       
 10627     __ string_indexof($str1$$Register, $str2$$Register,
       
 10628                       $cnt1$$Register, $cnt2$$Register,
       
 10629                       (-1), $result$$Register,
       
 10630                       $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
       
 10631   %}
       
 10632   ins_pipe( pipe_slow );
       
 10633 %}
       
 10634 
       
 10635 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
       
 10636                          rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
       
 10637 %{
       
 10638   predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
       
 10639   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
       
 10640   effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
       
 10641 
       
 10642   format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
       
 10643   ins_encode %{
       
 10644     __ string_indexof($str1$$Register, $str2$$Register,
       
 10645                       $cnt1$$Register, $cnt2$$Register,
       
 10646                       (-1), $result$$Register,
       
 10647                       $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
       
 10648   %}
       
 10649   ins_pipe( pipe_slow );
       
 10650 %}
       
 10651 
       
 10652 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch,
       
 10653                               rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr)
       
 10654 %{
       
 10655   predicate(UseSSE42Intrinsics);
       
 10656   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
       
 10657   effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
       
 10658   format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result   // KILL all" %}
       
 10659   ins_encode %{
       
 10660     __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
       
 10661                            $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register);
 10507   %}
 10662   %}
 10508   ins_pipe( pipe_slow );
 10663   ins_pipe( pipe_slow );
 10509 %}
 10664 %}
 10510 
 10665 
 10511 // fast string equals
 10666 // fast string equals
 10515   match(Set result (StrEquals (Binary str1 str2) cnt));
 10670   match(Set result (StrEquals (Binary str1 str2) cnt));
 10516   effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
 10671   effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
 10517 
 10672 
 10518   format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
 10673   format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
 10519   ins_encode %{
 10674   ins_encode %{
 10520     __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
 10675     __ arrays_equals(false, $str1$$Register, $str2$$Register,
 10521                           $cnt$$Register, $result$$Register, $tmp3$$Register,
 10676                      $cnt$$Register, $result$$Register, $tmp3$$Register,
 10522                           $tmp1$$XMMRegister, $tmp2$$XMMRegister);
 10677                      $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
 10523   %}
 10678   %}
 10524   ins_pipe( pipe_slow );
 10679   ins_pipe( pipe_slow );
 10525 %}
 10680 %}
 10526 
 10681 
 10527 // fast array equals
 10682 // fast array equals
 10528 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
 10683 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
 10529                       regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
 10684                        regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
 10530 %{
 10685 %{
       
 10686   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
 10531   match(Set result (AryEq ary1 ary2));
 10687   match(Set result (AryEq ary1 ary2));
 10532   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
 10688   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
 10533   //ins_cost(300);
 10689 
 10534 
 10690   format %{ "Array Equals byte[] $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
 10535   format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
 10691   ins_encode %{
 10536   ins_encode %{
 10692     __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
 10537     __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
 10693                      $tmp3$$Register, $result$$Register, $tmp4$$Register,
 10538                           $tmp3$$Register, $result$$Register, $tmp4$$Register,
 10694                      $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
 10539                           $tmp1$$XMMRegister, $tmp2$$XMMRegister);
 10695   %}
       
 10696   ins_pipe( pipe_slow );
       
 10697 %}
       
 10698 
       
 10699 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
       
 10700                       regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
       
 10701 %{
       
 10702   predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
       
 10703   match(Set result (AryEq ary1 ary2));
       
 10704   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
       
 10705 
       
 10706   format %{ "Array Equals char[] $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
       
 10707   ins_encode %{
       
 10708     __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
       
 10709                      $tmp3$$Register, $result$$Register, $tmp4$$Register,
       
 10710                      $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */);
       
 10711   %}
       
 10712   ins_pipe( pipe_slow );
       
 10713 %}
       
 10714 
       
 10715 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result,
       
 10716                       regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
       
 10717 %{
       
 10718   match(Set result (HasNegatives ary1 len));
       
 10719   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
       
 10720 
       
 10721   format %{ "has negatives byte[] $ary1,$len -> $result   // KILL $tmp1, $tmp2, $tmp3" %}
       
 10722   ins_encode %{
       
 10723     __ has_negatives($ary1$$Register, $len$$Register,
       
 10724                      $result$$Register, $tmp3$$Register,
       
 10725                      $tmp1$$XMMRegister, $tmp2$$XMMRegister);
       
 10726   %}
       
 10727   ins_pipe( pipe_slow );
       
 10728 %}
       
 10729 
       
 10730 // fast char[] to byte[] compression
       
 10731 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4,
       
 10732                          rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
       
 10733   match(Set result (StrCompressedCopy src (Binary dst len)));
       
 10734   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
       
 10735 
       
 10736   format %{ "String Compress $src,$dst -> $result    // KILL RAX, RCX, RDX" %}
       
 10737   ins_encode %{
       
 10738     __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
       
 10739                            $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
       
 10740                            $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
       
 10741   %}
       
 10742   ins_pipe( pipe_slow );
       
 10743 %}
       
 10744 
       
 10745 // fast byte[] to char[] inflation
       
 10746 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len,
       
 10747                         regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{
       
 10748   match(Set dummy (StrInflatedCopy src (Binary dst len)));
       
 10749   effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
       
 10750 
       
 10751   format %{ "String Inflate $src,$dst    // KILL $tmp1, $tmp2" %}
       
 10752   ins_encode %{
       
 10753     __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
       
 10754                           $tmp1$$XMMRegister, $tmp2$$Register);
 10540   %}
 10755   %}
 10541   ins_pipe( pipe_slow );
 10756   ins_pipe( pipe_slow );
 10542 %}
 10757 %}
 10543 
 10758 
 10544 // encode char[] to byte[] in ISO_8859_1
 10759 // encode char[] to byte[] in ISO_8859_1