< prev index next >

src/cpu/x86/vm/x86_32.ad

Print this page
rev 5781 : 8173770: Image conversion improvements
Reviewed-by: kvn, vlivanov, dlong, rhalade, mschoene, iignatyev
rev 5789 : 8185502: No overflow operator on OpenJDK 7
Summary: Remove usage of overflow in x86_32.ad
Reviewed-by: roland, andrew

*** 4543,4552 **** --- 4543,4572 ---- match(RegFlags); format %{ "FLAGS_LEGT" %} 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 ); constraint(ALLOC_IN_RC(fp_dbl_reg)); match(RegD);
*** 5056,5066 **** less_equal (0x0D0); greater (0x1D0); %} %} ! // Comparision Code used in long compares operand cmpOp_commute() %{ match(Bool); format %{ "" %} interface(COND_INTER) %{ --- 5076,5086 ---- less_equal (0x0D0); greater (0x1D0); %} %} ! // Comparison Code used in long compares operand cmpOp_commute() %{ match(Bool); format %{ "" %} interface(COND_INTER) %{
*** 5071,5080 **** --- 5091,5115 ---- less_equal(0xD, "ge"); greater(0xC, "l"); %} %} + // 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"); + %} + %} + //----------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 // instructions for every form of operand when the instruction accepts // multiple operand types with the same basic encoding and format. The classic
*** 12500,12509 **** --- 12535,12582 ---- expand %{ jmpCon(cmp,flags,labl); // JLT or JGE... %} %} + //====== + // 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))); 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 )); ins_cost(400);
*** 12628,12637 **** --- 12701,12745 ---- expand %{ jmpCon(cmp,flags,labl); // JEQ or JNE... %} %} + //====== + // 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))); predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne )); ins_cost(400);
*** 12761,12770 **** --- 12869,12918 ---- expand %{ jmpCon(cmp,flags,labl); // JGT or JLE... %} %} + //====== + // 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))); predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt )); ins_cost(400);
< prev index next >