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 |