3946 match(RegFlags); |
3946 match(RegFlags); |
3947 format %{ "FLAGS_LEGT" %} |
3947 format %{ "FLAGS_LEGT" %} |
3948 interface(REG_INTER); |
3948 interface(REG_INTER); |
3949 %} |
3949 %} |
3950 |
3950 |
|
3951 // Condition Code Register used by unsigned long compare |
|
3952 operand flagsReg_ulong_LTGE() %{ |
|
3953 constraint(ALLOC_IN_RC(int_flags)); |
|
3954 match(RegFlags); |
|
3955 format %{ "FLAGS_U_LTGE" %} |
|
3956 interface(REG_INTER); |
|
3957 %} |
|
3958 operand flagsReg_ulong_EQNE() %{ |
|
3959 constraint(ALLOC_IN_RC(int_flags)); |
|
3960 match(RegFlags); |
|
3961 format %{ "FLAGS_U_EQNE" %} |
|
3962 interface(REG_INTER); |
|
3963 %} |
|
3964 operand flagsReg_ulong_LEGT() %{ |
|
3965 constraint(ALLOC_IN_RC(int_flags)); |
|
3966 match(RegFlags); |
|
3967 format %{ "FLAGS_U_LEGT" %} |
|
3968 interface(REG_INTER); |
|
3969 %} |
|
3970 |
3951 // Float register operands |
3971 // Float register operands |
3952 operand regDPR() %{ |
3972 operand regDPR() %{ |
3953 predicate( UseSSE < 2 ); |
3973 predicate( UseSSE < 2 ); |
3954 constraint(ALLOC_IN_RC(fp_dbl_reg)); |
3974 constraint(ALLOC_IN_RC(fp_dbl_reg)); |
3955 match(RegD); |
3975 match(RegD); |
4471 overflow(0x0, "o"); // not really supported by the instruction |
4491 overflow(0x0, "o"); // not really supported by the instruction |
4472 no_overflow(0x1, "no"); // not really supported by the instruction |
4492 no_overflow(0x1, "no"); // not really supported by the instruction |
4473 %} |
4493 %} |
4474 %} |
4494 %} |
4475 |
4495 |
4476 // Comparision Code used in long compares |
4496 // Comparison Code used in long compares |
4477 operand cmpOp_commute() %{ |
4497 operand cmpOp_commute() %{ |
4478 match(Bool); |
4498 match(Bool); |
4479 |
4499 |
4480 format %{ "" %} |
4500 format %{ "" %} |
4481 interface(COND_INTER) %{ |
4501 interface(COND_INTER) %{ |
4483 not_equal(0x5, "ne"); |
4503 not_equal(0x5, "ne"); |
4484 less(0xF, "g"); |
4504 less(0xF, "g"); |
4485 greater_equal(0xE, "le"); |
4505 greater_equal(0xE, "le"); |
4486 less_equal(0xD, "ge"); |
4506 less_equal(0xD, "ge"); |
4487 greater(0xC, "l"); |
4507 greater(0xC, "l"); |
|
4508 overflow(0x0, "o"); |
|
4509 no_overflow(0x1, "no"); |
|
4510 %} |
|
4511 %} |
|
4512 |
|
4513 // Comparison Code used in unsigned long compares |
|
4514 operand cmpOpU_commute() %{ |
|
4515 match(Bool); |
|
4516 |
|
4517 format %{ "" %} |
|
4518 interface(COND_INTER) %{ |
|
4519 equal(0x4, "e"); |
|
4520 not_equal(0x5, "ne"); |
|
4521 less(0x7, "nbe"); |
|
4522 greater_equal(0x6, "be"); |
|
4523 less_equal(0x3, "nb"); |
|
4524 greater(0x2, "b"); |
4488 overflow(0x0, "o"); |
4525 overflow(0x0, "o"); |
4489 no_overflow(0x1, "no"); |
4526 no_overflow(0x1, "no"); |
4490 %} |
4527 %} |
4491 %} |
4528 %} |
4492 |
4529 |
12380 expand %{ |
12417 expand %{ |
12381 jmpCon(cmp,flags,labl); // JLT or JGE... |
12418 jmpCon(cmp,flags,labl); // JLT or JGE... |
12382 %} |
12419 %} |
12383 %} |
12420 %} |
12384 |
12421 |
|
12422 //====== |
|
12423 // Manifest a CmpUL result in the normal flags. Only good for LT or GE |
|
12424 // compares. Can be used for LE or GT compares by reversing arguments. |
|
12425 // NOT GOOD FOR EQ/NE tests. |
|
12426 instruct cmpUL_zero_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src, immL0 zero) %{ |
|
12427 match(Set flags (CmpUL src zero)); |
|
12428 ins_cost(100); |
|
12429 format %{ "TEST $src.hi,$src.hi" %} |
|
12430 opcode(0x85); |
|
12431 ins_encode(OpcP, RegReg_Hi2(src, src)); |
|
12432 ins_pipe(ialu_cr_reg_reg); |
|
12433 %} |
|
12434 |
|
12435 // Manifest a CmpUL result in the normal flags. Only good for LT or GE |
|
12436 // compares. Can be used for LE or GT compares by reversing arguments. |
|
12437 // NOT GOOD FOR EQ/NE tests. |
|
12438 instruct cmpUL_reg_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src1, eRegL src2, rRegI tmp) %{ |
|
12439 match(Set flags (CmpUL src1 src2)); |
|
12440 effect(TEMP tmp); |
|
12441 ins_cost(300); |
|
12442 format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t" |
|
12443 "MOV $tmp,$src1.hi\n\t" |
|
12444 "SBB $tmp,$src2.hi\t! Compute flags for unsigned long compare" %} |
|
12445 ins_encode(long_cmp_flags2(src1, src2, tmp)); |
|
12446 ins_pipe(ialu_cr_reg_reg); |
|
12447 %} |
|
12448 |
|
12449 // Unsigned long compares reg < zero/req OR reg >= zero/req. |
|
12450 // Just a wrapper for a normal branch, plus the predicate test. |
|
12451 instruct cmpUL_LTGE(cmpOpU cmp, flagsReg_ulong_LTGE flags, label labl) %{ |
|
12452 match(If cmp flags); |
|
12453 effect(USE labl); |
|
12454 predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); |
|
12455 expand %{ |
|
12456 jmpCon(cmp, flags, labl); // JLT or JGE... |
|
12457 %} |
|
12458 %} |
|
12459 |
12385 // Compare 2 longs and CMOVE longs. |
12460 // Compare 2 longs and CMOVE longs. |
12386 instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{ |
12461 instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{ |
12387 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); |
12462 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); |
12388 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge )); |
12463 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge )); |
12389 ins_cost(400); |
12464 ins_cost(400); |
12505 match(If cmp flags); |
12580 match(If cmp flags); |
12506 effect(USE labl); |
12581 effect(USE labl); |
12507 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); |
12582 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); |
12508 expand %{ |
12583 expand %{ |
12509 jmpCon(cmp,flags,labl); // JEQ or JNE... |
12584 jmpCon(cmp,flags,labl); // JEQ or JNE... |
|
12585 %} |
|
12586 %} |
|
12587 |
|
12588 //====== |
|
12589 // Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares. |
|
12590 instruct cmpUL_zero_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src, immL0 zero, rRegI tmp) %{ |
|
12591 match(Set flags (CmpUL src zero)); |
|
12592 effect(TEMP tmp); |
|
12593 ins_cost(200); |
|
12594 format %{ "MOV $tmp,$src.lo\n\t" |
|
12595 "OR $tmp,$src.hi\t! Unsigned long is EQ/NE 0?" %} |
|
12596 ins_encode(long_cmp_flags0(src, tmp)); |
|
12597 ins_pipe(ialu_reg_reg_long); |
|
12598 %} |
|
12599 |
|
12600 // Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares. |
|
12601 instruct cmpUL_reg_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src1, eRegL src2) %{ |
|
12602 match(Set flags (CmpUL src1 src2)); |
|
12603 ins_cost(200+300); |
|
12604 format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t" |
|
12605 "JNE,s skip\n\t" |
|
12606 "CMP $src1.hi,$src2.hi\n\t" |
|
12607 "skip:\t" %} |
|
12608 ins_encode(long_cmp_flags1(src1, src2)); |
|
12609 ins_pipe(ialu_cr_reg_reg); |
|
12610 %} |
|
12611 |
|
12612 // Unsigned long compare reg == zero/reg OR reg != zero/reg |
|
12613 // Just a wrapper for a normal branch, plus the predicate test. |
|
12614 instruct cmpUL_EQNE(cmpOpU cmp, flagsReg_ulong_EQNE flags, label labl) %{ |
|
12615 match(If cmp flags); |
|
12616 effect(USE labl); |
|
12617 predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); |
|
12618 expand %{ |
|
12619 jmpCon(cmp, flags, labl); // JEQ or JNE... |
12510 %} |
12620 %} |
12511 %} |
12621 %} |
12512 |
12622 |
12513 // Compare 2 longs and CMOVE longs. |
12623 // Compare 2 longs and CMOVE longs. |
12514 instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{ |
12624 instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{ |
12638 effect(USE labl); |
12748 effect(USE labl); |
12639 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le ); |
12749 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le ); |
12640 ins_cost(300); |
12750 ins_cost(300); |
12641 expand %{ |
12751 expand %{ |
12642 jmpCon(cmp,flags,labl); // JGT or JLE... |
12752 jmpCon(cmp,flags,labl); // JGT or JLE... |
|
12753 %} |
|
12754 %} |
|
12755 |
|
12756 //====== |
|
12757 // Manifest a CmpUL result in the normal flags. Only good for LE or GT compares. |
|
12758 // Same as cmpUL_reg_flags_LEGT except must negate src |
|
12759 instruct cmpUL_zero_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src, immL0 zero, rRegI tmp) %{ |
|
12760 match(Set flags (CmpUL src zero)); |
|
12761 effect(TEMP tmp); |
|
12762 ins_cost(300); |
|
12763 format %{ "XOR $tmp,$tmp\t# Unsigned long compare for -$src < 0, use commuted test\n\t" |
|
12764 "CMP $tmp,$src.lo\n\t" |
|
12765 "SBB $tmp,$src.hi\n\t" %} |
|
12766 ins_encode(long_cmp_flags3(src, tmp)); |
|
12767 ins_pipe(ialu_reg_reg_long); |
|
12768 %} |
|
12769 |
|
12770 // Manifest a CmpUL result in the normal flags. Only good for LE or GT compares. |
|
12771 // Same as cmpUL_reg_flags_LTGE except operands swapped. Swapping operands |
|
12772 // requires a commuted test to get the same result. |
|
12773 instruct cmpUL_reg_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src1, eRegL src2, rRegI tmp) %{ |
|
12774 match(Set flags (CmpUL src1 src2)); |
|
12775 effect(TEMP tmp); |
|
12776 ins_cost(300); |
|
12777 format %{ "CMP $src2.lo,$src1.lo\t! Unsigned long compare, swapped operands, use with commuted test\n\t" |
|
12778 "MOV $tmp,$src2.hi\n\t" |
|
12779 "SBB $tmp,$src1.hi\t! Compute flags for unsigned long compare" %} |
|
12780 ins_encode(long_cmp_flags2( src2, src1, tmp)); |
|
12781 ins_pipe(ialu_cr_reg_reg); |
|
12782 %} |
|
12783 |
|
12784 // Unsigned long compares reg < zero/req OR reg >= zero/req. |
|
12785 // Just a wrapper for a normal branch, plus the predicate test |
|
12786 instruct cmpUL_LEGT(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, label labl) %{ |
|
12787 match(If cmp flags); |
|
12788 effect(USE labl); |
|
12789 predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le); |
|
12790 ins_cost(300); |
|
12791 expand %{ |
|
12792 jmpCon(cmp, flags, labl); // JGT or JLE... |
12643 %} |
12793 %} |
12644 %} |
12794 %} |
12645 |
12795 |
12646 // Compare 2 longs and CMOVE longs. |
12796 // Compare 2 longs and CMOVE longs. |
12647 instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{ |
12797 instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{ |