Mercurial > hg > graal-jvmci-8
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) %{ |