< 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 >