Mercurial > hg > graal-jvmci-8
diff 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 |
line wrap: on
line diff
--- a/src/cpu/x86/vm/x86_32.ad Thu Feb 16 15:14:44 2017 -0800 +++ b/src/cpu/x86/vm/x86_32.ad Thu Mar 30 15:28:33 2017 +0200 @@ -3948,6 +3948,26 @@ interface(REG_INTER); %} +// Condition Code Register used by unsigned long compare +operand flagsReg_ulong_LTGE() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + format %{ "FLAGS_U_LTGE" %} + interface(REG_INTER); +%} +operand flagsReg_ulong_EQNE() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + format %{ "FLAGS_U_EQNE" %} + interface(REG_INTER); +%} +operand flagsReg_ulong_LEGT() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + format %{ "FLAGS_U_LEGT" %} + interface(REG_INTER); +%} + // Float register operands operand regDPR() %{ predicate( UseSSE < 2 ); @@ -4473,7 +4493,7 @@ %} %} -// Comparision Code used in long compares +// Comparison Code used in long compares operand cmpOp_commute() %{ match(Bool); @@ -4490,6 +4510,23 @@ %} %} +// Comparison Code used in unsigned long compares +operand cmpOpU_commute() %{ + match(Bool); + + format %{ "" %} + interface(COND_INTER) %{ + equal(0x4, "e"); + not_equal(0x5, "ne"); + less(0x7, "nbe"); + greater_equal(0x6, "be"); + less_equal(0x3, "nb"); + greater(0x2, "b"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); + %} +%} + //----------OPERAND CLASSES---------------------------------------------------- // Operand Classes are groups of operands that are used as to simplify // instruction definitions by not requiring the AD writer to specify separate @@ -12382,6 +12419,44 @@ %} %} +//====== +// Manifest a CmpUL result in the normal flags. Only good for LT or GE +// compares. Can be used for LE or GT compares by reversing arguments. +// NOT GOOD FOR EQ/NE tests. +instruct cmpUL_zero_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src, immL0 zero) %{ + match(Set flags (CmpUL src zero)); + ins_cost(100); + format %{ "TEST $src.hi,$src.hi" %} + opcode(0x85); + ins_encode(OpcP, RegReg_Hi2(src, src)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Manifest a CmpUL result in the normal flags. Only good for LT or GE +// compares. Can be used for LE or GT compares by reversing arguments. +// NOT GOOD FOR EQ/NE tests. +instruct cmpUL_reg_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src1, eRegL src2, rRegI tmp) %{ + match(Set flags (CmpUL src1 src2)); + effect(TEMP tmp); + ins_cost(300); + format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t" + "MOV $tmp,$src1.hi\n\t" + "SBB $tmp,$src2.hi\t! Compute flags for unsigned long compare" %} + ins_encode(long_cmp_flags2(src1, src2, tmp)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Unsigned long compares reg < zero/req OR reg >= zero/req. +// Just a wrapper for a normal branch, plus the predicate test. +instruct cmpUL_LTGE(cmpOpU cmp, flagsReg_ulong_LTGE flags, label labl) %{ + match(If cmp flags); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + expand %{ + jmpCon(cmp, flags, labl); // JLT or JGE... + %} +%} + // Compare 2 longs and CMOVE longs. instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{ match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); @@ -12510,6 +12585,41 @@ %} %} +//====== +// Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares. +instruct cmpUL_zero_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src, immL0 zero, rRegI tmp) %{ + match(Set flags (CmpUL src zero)); + effect(TEMP tmp); + ins_cost(200); + format %{ "MOV $tmp,$src.lo\n\t" + "OR $tmp,$src.hi\t! Unsigned long is EQ/NE 0?" %} + ins_encode(long_cmp_flags0(src, tmp)); + ins_pipe(ialu_reg_reg_long); +%} + +// Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares. +instruct cmpUL_reg_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src1, eRegL src2) %{ + match(Set flags (CmpUL src1 src2)); + ins_cost(200+300); + format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t" + "JNE,s skip\n\t" + "CMP $src1.hi,$src2.hi\n\t" + "skip:\t" %} + ins_encode(long_cmp_flags1(src1, src2)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Unsigned long compare reg == zero/reg OR reg != zero/reg +// Just a wrapper for a normal branch, plus the predicate test. +instruct cmpUL_EQNE(cmpOpU cmp, flagsReg_ulong_EQNE flags, label labl) %{ + match(If cmp flags); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + expand %{ + jmpCon(cmp, flags, labl); // JEQ or JNE... + %} +%} + // Compare 2 longs and CMOVE longs. instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{ match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); @@ -12643,6 +12753,46 @@ %} %} +//====== +// Manifest a CmpUL result in the normal flags. Only good for LE or GT compares. +// Same as cmpUL_reg_flags_LEGT except must negate src +instruct cmpUL_zero_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src, immL0 zero, rRegI tmp) %{ + match(Set flags (CmpUL src zero)); + effect(TEMP tmp); + ins_cost(300); + format %{ "XOR $tmp,$tmp\t# Unsigned long compare for -$src < 0, use commuted test\n\t" + "CMP $tmp,$src.lo\n\t" + "SBB $tmp,$src.hi\n\t" %} + ins_encode(long_cmp_flags3(src, tmp)); + ins_pipe(ialu_reg_reg_long); +%} + +// Manifest a CmpUL result in the normal flags. Only good for LE or GT compares. +// Same as cmpUL_reg_flags_LTGE except operands swapped. Swapping operands +// requires a commuted test to get the same result. +instruct cmpUL_reg_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src1, eRegL src2, rRegI tmp) %{ + match(Set flags (CmpUL src1 src2)); + effect(TEMP tmp); + ins_cost(300); + format %{ "CMP $src2.lo,$src1.lo\t! Unsigned long compare, swapped operands, use with commuted test\n\t" + "MOV $tmp,$src2.hi\n\t" + "SBB $tmp,$src1.hi\t! Compute flags for unsigned long compare" %} + ins_encode(long_cmp_flags2( src2, src1, tmp)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Unsigned long compares reg < zero/req OR reg >= zero/req. +// Just a wrapper for a normal branch, plus the predicate test +instruct cmpUL_LEGT(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, label labl) %{ + match(If cmp flags); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le); + ins_cost(300); + expand %{ + jmpCon(cmp, flags, labl); // JGT or JLE... + %} +%} + // Compare 2 longs and CMOVE longs. instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{ match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));