< prev index next >

src/cpu/x86/vm/x86_64.ad

Print this page




1620   offset -= br_size;
1621 
1622   // the short version of jmpConUCF2 contains multiple branches,
1623   // making the reach slightly less
1624   if (rule == jmpConUCF2_rule)
1625     return (-126 <= offset && offset <= 125);
1626   return (-128 <= offset && offset <= 127);
1627 }
1628 
1629 const bool Matcher::isSimpleConstant64(jlong value) {
1630   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1631   //return value == (int) value;  // Cf. storeImmL and immL32.
1632 
1633   // Probably always true, even if a temp register is required.
1634   return true;
1635 }
1636 
1637 // The ecx parameter to rep stosq for the ClearArray node is in words.
1638 const bool Matcher::init_array_count_is_in_bytes = false;
1639 
1640 // Threshold size for cleararray.
1641 const int Matcher::init_array_short_size = 8 * BytesPerLong;
1642 
1643 // No additional cost for CMOVL.
1644 const int Matcher::long_cmove_cost() { return 0; }
1645 
1646 // No CMOVF/CMOVD with SSE2
1647 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1648 
1649 // Does the CPU require late expand (see block.cpp for description of late expand)?
1650 const bool Matcher::require_postalloc_expand = false;
1651 
1652 // Should the Matcher clone shifts on addressing modes, expecting them
1653 // to be subsumed into complex addressing expressions or compute them
1654 // into registers?  True for Intel but false for most RISCs
1655 const bool Matcher::clone_shift_expressions = true;
1656 
1657 // Do we need to mask the count passed to shift instructions or does
1658 // the cpu only look at the lower 5/6 bits anyway?
1659 const bool Matcher::need_masked_shift_count = false;
1660 
1661 bool Matcher::narrow_oop_use_complex_address() {
1662   assert(UseCompressedOops, "only for compressed oops code");


10443   ins_pipe( pipe_slow );
10444 %}
10445 
10446 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10447   match(Set dst (MoveL2D src));
10448   effect(DEF dst, USE src);
10449   ins_cost(100);
10450   format %{ "movd    $dst,$src\t# MoveL2D" %}
10451   ins_encode %{
10452      __ movdq($dst$$XMMRegister, $src$$Register);
10453   %}
10454   ins_pipe( pipe_slow );
10455 %}
10456 
10457 
10458 // =======================================================================
10459 // fast clearing of an array
10460 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10461                   rFlagsReg cr)
10462 %{
10463   predicate(!UseFastStosb);















10464   match(Set dummy (ClearArray cnt base));
10465   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10466 
10467   format %{ "xorq    rax, rax\t# ClearArray:\n\t"
10468             "rep     stosq\t# Store rax to *rdi++ while rcx--" %}
10469   ins_encode %{
10470     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10471   %}
10472   ins_pipe(pipe_slow);
10473 %}
10474 
10475 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10476                         rFlagsReg cr)
10477 %{
10478   predicate(UseFastStosb);















10479   match(Set dummy (ClearArray cnt base));
10480   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10481   format %{ "xorq    rax, rax\t# ClearArray:\n\t"
10482             "shlq    rcx,3\t# Convert doublewords to bytes\n\t"
10483             "rep     stosb\t# Store rax to *rdi++ while rcx--" %}
10484   ins_encode %{
10485     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10486   %}
10487   ins_pipe( pipe_slow );
10488 %}
10489 
10490 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
10491                          rax_RegI result, regD tmp1, rFlagsReg cr)
10492 %{
10493   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
10494   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10495   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
10496 
10497   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
10498   ins_encode %{
10499     __ string_compare($str1$$Register, $str2$$Register,
10500                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
10501                       $tmp1$$XMMRegister, StrIntrinsicNode::LL);
10502   %}
10503   ins_pipe( pipe_slow );
10504 %}
10505 




1620   offset -= br_size;
1621 
1622   // the short version of jmpConUCF2 contains multiple branches,
1623   // making the reach slightly less
1624   if (rule == jmpConUCF2_rule)
1625     return (-126 <= offset && offset <= 125);
1626   return (-128 <= offset && offset <= 127);
1627 }
1628 
1629 const bool Matcher::isSimpleConstant64(jlong value) {
1630   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1631   //return value == (int) value;  // Cf. storeImmL and immL32.
1632 
1633   // Probably always true, even if a temp register is required.
1634   return true;
1635 }
1636 
1637 // The ecx parameter to rep stosq for the ClearArray node is in words.
1638 const bool Matcher::init_array_count_is_in_bytes = false;
1639 



1640 // No additional cost for CMOVL.
1641 const int Matcher::long_cmove_cost() { return 0; }
1642 
1643 // No CMOVF/CMOVD with SSE2
1644 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1645 
1646 // Does the CPU require late expand (see block.cpp for description of late expand)?
1647 const bool Matcher::require_postalloc_expand = false;
1648 
1649 // Should the Matcher clone shifts on addressing modes, expecting them
1650 // to be subsumed into complex addressing expressions or compute them
1651 // into registers?  True for Intel but false for most RISCs
1652 const bool Matcher::clone_shift_expressions = true;
1653 
1654 // Do we need to mask the count passed to shift instructions or does
1655 // the cpu only look at the lower 5/6 bits anyway?
1656 const bool Matcher::need_masked_shift_count = false;
1657 
1658 bool Matcher::narrow_oop_use_complex_address() {
1659   assert(UseCompressedOops, "only for compressed oops code");


10440   ins_pipe( pipe_slow );
10441 %}
10442 
10443 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10444   match(Set dst (MoveL2D src));
10445   effect(DEF dst, USE src);
10446   ins_cost(100);
10447   format %{ "movd    $dst,$src\t# MoveL2D" %}
10448   ins_encode %{
10449      __ movdq($dst$$XMMRegister, $src$$Register);
10450   %}
10451   ins_pipe( pipe_slow );
10452 %}
10453 
10454 
10455 // =======================================================================
10456 // fast clearing of an array
10457 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10458                   rFlagsReg cr)
10459 %{
10460   predicate(!UseFastStosb && !((ClearArrayNode*)n)->is_large());
10461   match(Set dummy (ClearArray cnt base));
10462   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10463 
10464   format %{ "xorq    rax, rax\t# ClearArray:\n\t"
10465             "rep     stosq\t# Store rax to *rdi++ while rcx--" %}
10466   ins_encode %{
10467     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false);
10468   %}
10469   ins_pipe(pipe_slow);
10470 %}
10471 
10472 instruct rep_stos_known_large(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10473                   rFlagsReg cr)
10474 %{
10475   predicate(!UseFastStosb && ((ClearArrayNode*)n)->is_large());
10476   match(Set dummy (ClearArray cnt base));
10477   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10478 
10479   format %{ "xorq    rax, rax\t# ClearArray:\n\t"
10480             "rep     stosq\t# Store rax to *rdi++ while rcx--" %}
10481   ins_encode %{
10482     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true);
10483   %}
10484   ins_pipe(pipe_slow);
10485 %}
10486 
10487 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10488                         rFlagsReg cr)
10489 %{
10490   predicate(UseFastStosb && !((ClearArrayNode*)n)->is_large());
10491   match(Set dummy (ClearArray cnt base));
10492   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10493   format %{ "xorq    rax, rax\t# ClearArray:\n\t"
10494             "shlq    rcx,3\t# Convert doublewords to bytes\n\t"
10495             "rep     stosb\t# Store rax to *rdi++ while rcx--" %}
10496   ins_encode %{
10497     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false);
10498   %}
10499   ins_pipe( pipe_slow );
10500 %}
10501 
10502 instruct rep_fast_stosb_known_large(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10503                         rFlagsReg cr)
10504 %{
10505   predicate(UseFastStosb && ((ClearArrayNode*)n)->is_large());
10506   match(Set dummy (ClearArray cnt base));
10507   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10508   format %{ "xorq    rax, rax\t# ClearArray:\n\t"
10509             "shlq    rcx,3\t# Convert doublewords to bytes\n\t"
10510             "rep     stosb\t# Store rax to *rdi++ while rcx--" %}
10511   ins_encode %{
10512     __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true);
10513   %}
10514   ins_pipe( pipe_slow );
10515 %}
10516 
10517 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
10518                          rax_RegI result, regD tmp1, rFlagsReg cr)
10519 %{
10520   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
10521   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10522   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
10523 
10524   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
10525   ins_encode %{
10526     __ string_compare($str1$$Register, $str2$$Register,
10527                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
10528                       $tmp1$$XMMRegister, StrIntrinsicNode::LL);
10529   %}
10530   ins_pipe( pipe_slow );
10531 %}
10532 


< prev index next >