comparison src/cpu/x86/vm/x86_32.ad @ 24206:37ba410ffd43 jdk8u141-b08

8173770: Image conversion improvements Reviewed-by: kvn, vlivanov, dlong, rhalade, mschoene, iignatyev
author thartmann
date Thu, 30 Mar 2017 15:28:33 +0200
parents c3d0bd36ab28
children 719853999215
comparison
equal deleted inserted replaced
24205:b1f3fbe39975 24206:37ba410ffd43
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) %{