< 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


4528 // Condition Code Register used by long compare
4529 operand flagsReg_long_LTGE() %{
4530   constraint(ALLOC_IN_RC(int_flags));
4531   match(RegFlags);
4532   format %{ "FLAGS_LTGE" %}
4533   interface(REG_INTER);
4534 %}
4535 operand flagsReg_long_EQNE() %{
4536   constraint(ALLOC_IN_RC(int_flags));
4537   match(RegFlags);
4538   format %{ "FLAGS_EQNE" %}
4539   interface(REG_INTER);
4540 %}
4541 operand flagsReg_long_LEGT() %{
4542   constraint(ALLOC_IN_RC(int_flags));
4543   match(RegFlags);
4544   format %{ "FLAGS_LEGT" %}
4545   interface(REG_INTER);
4546 %}
4547 




















4548 // Float register operands
4549 operand regDPR() %{
4550   predicate( UseSSE < 2 );
4551   constraint(ALLOC_IN_RC(fp_dbl_reg));
4552   match(RegD);
4553   match(regDPR1);
4554   match(regDPR2);
4555   format %{ %}
4556   interface(REG_INTER);
4557 %}
4558 
4559 operand regDPR1(regDPR reg) %{
4560   predicate( UseSSE < 2 );
4561   constraint(ALLOC_IN_RC(fp_dbl_reg0));
4562   match(reg);
4563   format %{ "FPR1" %}
4564   interface(REG_INTER);
4565 %}
4566 
4567 operand regDPR2(regDPR reg) %{


5041     less_equal(0x6, "be");
5042     greater(0x7, "nbe");
5043   %}
5044 %}
5045 
5046 // Comparison Code for FP conditional move
5047 operand cmpOp_fcmov() %{
5048   match(Bool);
5049 
5050   format %{ "" %}
5051   interface(COND_INTER) %{
5052     equal        (0x0C8);
5053     not_equal    (0x1C8);
5054     less         (0x0C0);
5055     greater_equal(0x1C0);
5056     less_equal   (0x0D0);
5057     greater      (0x1D0);
5058   %}
5059 %}
5060 
5061 // Comparision Code used in long compares
5062 operand cmpOp_commute() %{
5063   match(Bool);
5064 
5065   format %{ "" %}
5066   interface(COND_INTER) %{
5067     equal(0x4, "e");
5068     not_equal(0x5, "ne");
5069     less(0xF, "g");
5070     greater_equal(0xE, "le");
5071     less_equal(0xD, "ge");
5072     greater(0xC, "l");
5073   %}
5074 %}
5075 















5076 //----------OPERAND CLASSES----------------------------------------------------
5077 // Operand Classes are groups of operands that are used as to simplify
5078 // instruction definitions by not requiring the AD writer to specify separate
5079 // instructions for every form of operand when the instruction accepts
5080 // multiple operand types with the same basic encoding and format.  The classic
5081 // case of this is memory operands.
5082 
5083 opclass memory(direct, indirect, indOffset8, indOffset32, indOffset32X, indIndexOffset,
5084                indIndex, indIndexScale, indIndexScaleOffset);
5085 
5086 // Long memory operations are encoded in 2 instructions and a +4 offset.
5087 // This means some kind of offset is always required and you cannot use
5088 // an oop as the offset (done when working on static globals).
5089 opclass long_memory(direct, indirect, indOffset8, indOffset32, indIndexOffset,
5090                     indIndex, indIndexScale, indIndexScaleOffset);
5091 
5092 
5093 //----------PIPELINE-----------------------------------------------------------
5094 // Rules which define the behavior of the target architectures pipeline.
5095 pipeline %{


12485   effect( TEMP tmp );
12486   ins_cost(300);
12487   format %{ "CMP    $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12488             "MOV    $tmp,$src1.hi\n\t"
12489             "SBB    $tmp,$src2.hi\t! Compute flags for long compare" %}
12490   ins_encode( long_cmp_flags2( src1, src2, tmp ) );
12491   ins_pipe( ialu_cr_reg_reg );
12492 %}
12493 
12494 // Long compares reg < zero/req OR reg >= zero/req.
12495 // Just a wrapper for a normal branch, plus the predicate test.
12496 instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{
12497   match(If cmp flags);
12498   effect(USE labl);
12499   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12500   expand %{
12501     jmpCon(cmp,flags,labl);    // JLT or JGE...
12502   %}
12503 %}
12504 






































12505 // Compare 2 longs and CMOVE longs.
12506 instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{
12507   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
12508   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 ));
12509   ins_cost(400);
12510   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12511             "CMOV$cmp $dst.hi,$src.hi" %}
12512   opcode(0x0F,0x40);
12513   ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12514   ins_pipe( pipe_cmov_reg_long );
12515 %}
12516 
12517 instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{
12518   match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12519   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 ));
12520   ins_cost(500);
12521   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12522             "CMOV$cmp $dst.hi,$src.hi" %}
12523   opcode(0x0F,0x40);
12524   ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );


12613   ins_cost(200+300);
12614   format %{ "CMP    $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12615             "JNE,s  skip\n\t"
12616             "CMP    $src1.hi,$src2.hi\n\t"
12617      "skip:\t" %}
12618   ins_encode( long_cmp_flags1( src1, src2 ) );
12619   ins_pipe( ialu_cr_reg_reg );
12620 %}
12621 
12622 // Long compare reg == zero/reg OR reg != zero/reg
12623 // Just a wrapper for a normal branch, plus the predicate test.
12624 instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{
12625   match(If cmp flags);
12626   effect(USE labl);
12627   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
12628   expand %{
12629     jmpCon(cmp,flags,labl);    // JEQ or JNE...
12630   %}
12631 %}
12632 



































12633 // Compare 2 longs and CMOVE longs.
12634 instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{
12635   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
12636   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 ));
12637   ins_cost(400);
12638   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12639             "CMOV$cmp $dst.hi,$src.hi" %}
12640   opcode(0x0F,0x40);
12641   ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12642   ins_pipe( pipe_cmov_reg_long );
12643 %}
12644 
12645 instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{
12646   match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12647   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 ));
12648   ins_cost(500);
12649   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12650             "CMOV$cmp $dst.hi,$src.hi" %}
12651   opcode(0x0F,0x40);
12652   ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );


12743 instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, rRegI tmp ) %{
12744   match( Set flags (CmpL src1 src2 ));
12745   effect( TEMP tmp );
12746   ins_cost(300);
12747   format %{ "CMP    $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t"
12748             "MOV    $tmp,$src2.hi\n\t"
12749             "SBB    $tmp,$src1.hi\t! Compute flags for long compare" %}
12750   ins_encode( long_cmp_flags2( src2, src1, tmp ) );
12751   ins_pipe( ialu_cr_reg_reg );
12752 %}
12753 
12754 // Long compares reg < zero/req OR reg >= zero/req.
12755 // Just a wrapper for a normal branch, plus the predicate test
12756 instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{
12757   match(If cmp flags);
12758   effect(USE labl);
12759   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
12760   ins_cost(300);
12761   expand %{
12762     jmpCon(cmp,flags,labl);    // JGT or JLE...








































12763   %}
12764 %}
12765 
12766 // Compare 2 longs and CMOVE longs.
12767 instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{
12768   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
12769   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 ));
12770   ins_cost(400);
12771   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12772             "CMOV$cmp $dst.hi,$src.hi" %}
12773   opcode(0x0F,0x40);
12774   ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12775   ins_pipe( pipe_cmov_reg_long );
12776 %}
12777 
12778 instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{
12779   match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12780   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 ));
12781   ins_cost(500);
12782   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"




4528 // Condition Code Register used by long compare
4529 operand flagsReg_long_LTGE() %{
4530   constraint(ALLOC_IN_RC(int_flags));
4531   match(RegFlags);
4532   format %{ "FLAGS_LTGE" %}
4533   interface(REG_INTER);
4534 %}
4535 operand flagsReg_long_EQNE() %{
4536   constraint(ALLOC_IN_RC(int_flags));
4537   match(RegFlags);
4538   format %{ "FLAGS_EQNE" %}
4539   interface(REG_INTER);
4540 %}
4541 operand flagsReg_long_LEGT() %{
4542   constraint(ALLOC_IN_RC(int_flags));
4543   match(RegFlags);
4544   format %{ "FLAGS_LEGT" %}
4545   interface(REG_INTER);
4546 %}
4547 
4548 // Condition Code Register used by unsigned long compare
4549 operand flagsReg_ulong_LTGE() %{
4550   constraint(ALLOC_IN_RC(int_flags));
4551   match(RegFlags);
4552   format %{ "FLAGS_U_LTGE" %}
4553   interface(REG_INTER);
4554 %}
4555 operand flagsReg_ulong_EQNE() %{
4556   constraint(ALLOC_IN_RC(int_flags));
4557   match(RegFlags);
4558   format %{ "FLAGS_U_EQNE" %}
4559   interface(REG_INTER);
4560 %}
4561 operand flagsReg_ulong_LEGT() %{
4562   constraint(ALLOC_IN_RC(int_flags));
4563   match(RegFlags);
4564   format %{ "FLAGS_U_LEGT" %}
4565   interface(REG_INTER);
4566 %}
4567 
4568 // Float register operands
4569 operand regDPR() %{
4570   predicate( UseSSE < 2 );
4571   constraint(ALLOC_IN_RC(fp_dbl_reg));
4572   match(RegD);
4573   match(regDPR1);
4574   match(regDPR2);
4575   format %{ %}
4576   interface(REG_INTER);
4577 %}
4578 
4579 operand regDPR1(regDPR reg) %{
4580   predicate( UseSSE < 2 );
4581   constraint(ALLOC_IN_RC(fp_dbl_reg0));
4582   match(reg);
4583   format %{ "FPR1" %}
4584   interface(REG_INTER);
4585 %}
4586 
4587 operand regDPR2(regDPR reg) %{


5061     less_equal(0x6, "be");
5062     greater(0x7, "nbe");
5063   %}
5064 %}
5065 
5066 // Comparison Code for FP conditional move
5067 operand cmpOp_fcmov() %{
5068   match(Bool);
5069 
5070   format %{ "" %}
5071   interface(COND_INTER) %{
5072     equal        (0x0C8);
5073     not_equal    (0x1C8);
5074     less         (0x0C0);
5075     greater_equal(0x1C0);
5076     less_equal   (0x0D0);
5077     greater      (0x1D0);
5078   %}
5079 %}
5080 
5081 // Comparison Code used in long compares
5082 operand cmpOp_commute() %{
5083   match(Bool);
5084 
5085   format %{ "" %}
5086   interface(COND_INTER) %{
5087     equal(0x4, "e");
5088     not_equal(0x5, "ne");
5089     less(0xF, "g");
5090     greater_equal(0xE, "le");
5091     less_equal(0xD, "ge");
5092     greater(0xC, "l");
5093   %}
5094 %}
5095 
5096 // Comparison Code used in unsigned long compares
5097 operand cmpOpU_commute() %{
5098   match(Bool);
5099 
5100   format %{ "" %}
5101   interface(COND_INTER) %{
5102     equal(0x4, "e");
5103     not_equal(0x5, "ne");
5104     less(0x7, "nbe");
5105     greater_equal(0x6, "be");
5106     less_equal(0x3, "nb");
5107     greater(0x2, "b");
5108   %}
5109 %}
5110 
5111 //----------OPERAND CLASSES----------------------------------------------------
5112 // Operand Classes are groups of operands that are used as to simplify
5113 // instruction definitions by not requiring the AD writer to specify separate
5114 // instructions for every form of operand when the instruction accepts
5115 // multiple operand types with the same basic encoding and format.  The classic
5116 // case of this is memory operands.
5117 
5118 opclass memory(direct, indirect, indOffset8, indOffset32, indOffset32X, indIndexOffset,
5119                indIndex, indIndexScale, indIndexScaleOffset);
5120 
5121 // Long memory operations are encoded in 2 instructions and a +4 offset.
5122 // This means some kind of offset is always required and you cannot use
5123 // an oop as the offset (done when working on static globals).
5124 opclass long_memory(direct, indirect, indOffset8, indOffset32, indIndexOffset,
5125                     indIndex, indIndexScale, indIndexScaleOffset);
5126 
5127 
5128 //----------PIPELINE-----------------------------------------------------------
5129 // Rules which define the behavior of the target architectures pipeline.
5130 pipeline %{


12520   effect( TEMP tmp );
12521   ins_cost(300);
12522   format %{ "CMP    $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12523             "MOV    $tmp,$src1.hi\n\t"
12524             "SBB    $tmp,$src2.hi\t! Compute flags for long compare" %}
12525   ins_encode( long_cmp_flags2( src1, src2, tmp ) );
12526   ins_pipe( ialu_cr_reg_reg );
12527 %}
12528 
12529 // Long compares reg < zero/req OR reg >= zero/req.
12530 // Just a wrapper for a normal branch, plus the predicate test.
12531 instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{
12532   match(If cmp flags);
12533   effect(USE labl);
12534   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12535   expand %{
12536     jmpCon(cmp,flags,labl);    // JLT or JGE...
12537   %}
12538 %}
12539 
12540 //======
12541 // Manifest a CmpUL result in the normal flags.  Only good for LT or GE
12542 // compares.  Can be used for LE or GT compares by reversing arguments.
12543 // NOT GOOD FOR EQ/NE tests.
12544 instruct cmpUL_zero_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src, immL0 zero) %{
12545   match(Set flags (CmpUL src zero));
12546   ins_cost(100);
12547   format %{ "TEST   $src.hi,$src.hi" %}
12548   opcode(0x85);
12549   ins_encode(OpcP, RegReg_Hi2(src, src));
12550   ins_pipe(ialu_cr_reg_reg);
12551 %}
12552 
12553 // Manifest a CmpUL result in the normal flags.  Only good for LT or GE
12554 // compares.  Can be used for LE or GT compares by reversing arguments.
12555 // NOT GOOD FOR EQ/NE tests.
12556 instruct cmpUL_reg_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src1, eRegL src2, rRegI tmp) %{
12557   match(Set flags (CmpUL src1 src2));
12558   effect(TEMP tmp);
12559   ins_cost(300);
12560   format %{ "CMP    $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t"
12561             "MOV    $tmp,$src1.hi\n\t"
12562             "SBB    $tmp,$src2.hi\t! Compute flags for unsigned long compare" %}
12563   ins_encode(long_cmp_flags2(src1, src2, tmp));
12564   ins_pipe(ialu_cr_reg_reg);
12565 %}
12566 
12567 // Unsigned long compares reg < zero/req OR reg >= zero/req.
12568 // Just a wrapper for a normal branch, plus the predicate test.
12569 instruct cmpUL_LTGE(cmpOpU cmp, flagsReg_ulong_LTGE flags, label labl) %{
12570   match(If cmp flags);
12571   effect(USE labl);
12572   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
12573   expand %{
12574     jmpCon(cmp, flags, labl);    // JLT or JGE...
12575   %}
12576 %}
12577 
12578 // Compare 2 longs and CMOVE longs.
12579 instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{
12580   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
12581   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 ));
12582   ins_cost(400);
12583   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12584             "CMOV$cmp $dst.hi,$src.hi" %}
12585   opcode(0x0F,0x40);
12586   ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12587   ins_pipe( pipe_cmov_reg_long );
12588 %}
12589 
12590 instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{
12591   match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12592   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 ));
12593   ins_cost(500);
12594   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12595             "CMOV$cmp $dst.hi,$src.hi" %}
12596   opcode(0x0F,0x40);
12597   ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );


12686   ins_cost(200+300);
12687   format %{ "CMP    $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12688             "JNE,s  skip\n\t"
12689             "CMP    $src1.hi,$src2.hi\n\t"
12690      "skip:\t" %}
12691   ins_encode( long_cmp_flags1( src1, src2 ) );
12692   ins_pipe( ialu_cr_reg_reg );
12693 %}
12694 
12695 // Long compare reg == zero/reg OR reg != zero/reg
12696 // Just a wrapper for a normal branch, plus the predicate test.
12697 instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{
12698   match(If cmp flags);
12699   effect(USE labl);
12700   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
12701   expand %{
12702     jmpCon(cmp,flags,labl);    // JEQ or JNE...
12703   %}
12704 %}
12705 
12706 //======
12707 // Manifest a CmpUL result in the normal flags.  Only good for EQ/NE compares.
12708 instruct cmpUL_zero_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src, immL0 zero, rRegI tmp) %{
12709   match(Set flags (CmpUL src zero));
12710   effect(TEMP tmp);
12711   ins_cost(200);
12712   format %{ "MOV    $tmp,$src.lo\n\t"
12713             "OR     $tmp,$src.hi\t! Unsigned long is EQ/NE 0?" %}
12714   ins_encode(long_cmp_flags0(src, tmp));
12715   ins_pipe(ialu_reg_reg_long);
12716 %}
12717 
12718 // Manifest a CmpUL result in the normal flags.  Only good for EQ/NE compares.
12719 instruct cmpUL_reg_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src1, eRegL src2) %{
12720   match(Set flags (CmpUL src1 src2));
12721   ins_cost(200+300);
12722   format %{ "CMP    $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t"
12723             "JNE,s  skip\n\t"
12724             "CMP    $src1.hi,$src2.hi\n\t"
12725      "skip:\t" %}
12726   ins_encode(long_cmp_flags1(src1, src2));
12727   ins_pipe(ialu_cr_reg_reg);
12728 %}
12729 
12730 // Unsigned long compare reg == zero/reg OR reg != zero/reg
12731 // Just a wrapper for a normal branch, plus the predicate test.
12732 instruct cmpUL_EQNE(cmpOpU cmp, flagsReg_ulong_EQNE flags, label labl) %{
12733   match(If cmp flags);
12734   effect(USE labl);
12735   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
12736   expand %{
12737     jmpCon(cmp, flags, labl);    // JEQ or JNE...
12738   %}
12739 %}
12740 
12741 // Compare 2 longs and CMOVE longs.
12742 instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{
12743   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
12744   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 ));
12745   ins_cost(400);
12746   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12747             "CMOV$cmp $dst.hi,$src.hi" %}
12748   opcode(0x0F,0x40);
12749   ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12750   ins_pipe( pipe_cmov_reg_long );
12751 %}
12752 
12753 instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{
12754   match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12755   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 ));
12756   ins_cost(500);
12757   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12758             "CMOV$cmp $dst.hi,$src.hi" %}
12759   opcode(0x0F,0x40);
12760   ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );


12851 instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, rRegI tmp ) %{
12852   match( Set flags (CmpL src1 src2 ));
12853   effect( TEMP tmp );
12854   ins_cost(300);
12855   format %{ "CMP    $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t"
12856             "MOV    $tmp,$src2.hi\n\t"
12857             "SBB    $tmp,$src1.hi\t! Compute flags for long compare" %}
12858   ins_encode( long_cmp_flags2( src2, src1, tmp ) );
12859   ins_pipe( ialu_cr_reg_reg );
12860 %}
12861 
12862 // Long compares reg < zero/req OR reg >= zero/req.
12863 // Just a wrapper for a normal branch, plus the predicate test
12864 instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{
12865   match(If cmp flags);
12866   effect(USE labl);
12867   predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
12868   ins_cost(300);
12869   expand %{
12870     jmpCon(cmp,flags,labl);    // JGT or JLE...
12871   %}
12872 %}
12873 
12874 //======
12875 // Manifest a CmpUL result in the normal flags.  Only good for LE or GT compares.
12876 // Same as cmpUL_reg_flags_LEGT except must negate src
12877 instruct cmpUL_zero_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src, immL0 zero, rRegI tmp) %{
12878   match(Set flags (CmpUL src zero));
12879   effect(TEMP tmp);
12880   ins_cost(300);
12881   format %{ "XOR    $tmp,$tmp\t# Unsigned long compare for -$src < 0, use commuted test\n\t"
12882             "CMP    $tmp,$src.lo\n\t"
12883             "SBB    $tmp,$src.hi\n\t" %}
12884   ins_encode(long_cmp_flags3(src, tmp));
12885   ins_pipe(ialu_reg_reg_long);
12886 %}
12887 
12888 // Manifest a CmpUL result in the normal flags.  Only good for LE or GT compares.
12889 // Same as cmpUL_reg_flags_LTGE except operands swapped.  Swapping operands
12890 // requires a commuted test to get the same result.
12891 instruct cmpUL_reg_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src1, eRegL src2, rRegI tmp) %{
12892   match(Set flags (CmpUL src1 src2));
12893   effect(TEMP tmp);
12894   ins_cost(300);
12895   format %{ "CMP    $src2.lo,$src1.lo\t! Unsigned long compare, swapped operands, use with commuted test\n\t"
12896             "MOV    $tmp,$src2.hi\n\t"
12897             "SBB    $tmp,$src1.hi\t! Compute flags for unsigned long compare" %}
12898   ins_encode(long_cmp_flags2( src2, src1, tmp));
12899   ins_pipe(ialu_cr_reg_reg);
12900 %}
12901 
12902 // Unsigned long compares reg < zero/req OR reg >= zero/req.
12903 // Just a wrapper for a normal branch, plus the predicate test
12904 instruct cmpUL_LEGT(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, label labl) %{
12905   match(If cmp flags);
12906   effect(USE labl);
12907   predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
12908   ins_cost(300);
12909   expand %{
12910     jmpCon(cmp, flags, labl);    // JGT or JLE...
12911   %}
12912 %}
12913 
12914 // Compare 2 longs and CMOVE longs.
12915 instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{
12916   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
12917   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 ));
12918   ins_cost(400);
12919   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12920             "CMOV$cmp $dst.hi,$src.hi" %}
12921   opcode(0x0F,0x40);
12922   ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12923   ins_pipe( pipe_cmov_reg_long );
12924 %}
12925 
12926 instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{
12927   match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12928   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 ));
12929   ins_cost(500);
12930   format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"


< prev index next >