diff -r 6987871cfb9b -r 95134e034042 src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Wed Aug 10 14:06:57 2011 -0700 +++ b/src/cpu/sparc/vm/sparc.ad Thu Aug 11 12:08:11 2011 -0700 @@ -1834,8 +1834,10 @@ // // NOTE: If the platform does not provide any short branch variants, then // this method should return false for offset 0. -bool Matcher::is_short_branch_offset(int rule, int offset) { - return false; +bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { + // The passed offset is relative to address of the branch. + // Don't need to adjust the offset. + return UseCBCond && Assembler::is_simm(offset, 12); } const bool Matcher::isSimpleConstant64(jlong value) { @@ -3315,6 +3317,7 @@ //----------Instruction Attributes--------------------------------------------- ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute ins_attrib ins_size(32); // Required size attribute (in bits) +ins_attrib ins_avoid_back_to_back(0); // instruction should not be generated back to back ins_attrib ins_short_branch(0); // Required flag: is this instruction a // non-matching short branch variant of some // long branch? @@ -3402,6 +3405,15 @@ interface(CONST_INTER); %} +// Integer Immediate: 5-bit +operand immI5() %{ + predicate(Assembler::is_simm(n->get_int(), 5)); + match(ConI); + op_cost(0); + format %{ %} + interface(CONST_INTER); +%} + // Integer Immediate: 0-bit operand immI0() %{ predicate(n->get_int() == 0); @@ -3625,6 +3637,15 @@ interface(CONST_INTER); %} +// Integer Immediate: 5-bit +operand immL5() %{ + predicate(n->get_long() == (int)n->get_long() && Assembler::is_simm((int)n->get_long(), 5)); + match(ConL); + op_cost(0); + format %{ %} + interface(CONST_INTER); +%} + // Long Immediate: 13-bit operand immL13() %{ predicate((-4096L < n->get_long()) && (n->get_long() <= 4095L)); @@ -5157,6 +5178,42 @@ MS : R; %} +// Compare and branch +pipe_class cmp_br_reg_reg(Universe br, cmpOp cmp, iRegI src1, iRegI src2, label labl, flagsReg cr) %{ + instruction_count(2); has_delay_slot; + cr : E(write); + src1 : R(read); + src2 : R(read); + IALU : R; + BR : R; +%} + +// Compare and branch +pipe_class cmp_br_reg_imm(Universe br, cmpOp cmp, iRegI src1, immI13 src2, label labl, flagsReg cr) %{ + instruction_count(2); has_delay_slot; + cr : E(write); + src1 : R(read); + IALU : R; + BR : R; +%} + +// Compare and branch using cbcond +pipe_class cbcond_reg_reg(Universe br, cmpOp cmp, iRegI src1, iRegI src2, label labl) %{ + single_instruction; + src1 : E(read); + src2 : E(read); + IALU : R; + BR : R; +%} + +// Compare and branch using cbcond +pipe_class cbcond_reg_imm(Universe br, cmpOp cmp, iRegI src1, immI5 src2, label labl) %{ + single_instruction; + src1 : E(read); + IALU : R; + BR : R; +%} + pipe_class br_fcc(Universe br, cmpOpF cc, flagsReg cr, label labl) %{ single_instruction_with_delay_slot; cr : E(read); @@ -9198,6 +9255,25 @@ ins_pipe(br); %} +// Direct Branch, short with no delay slot +instruct branch_short(label labl) %{ + match(Goto); + predicate(UseCBCond); + effect(USE labl); + + size(4); + ins_cost(BRANCH_COST); + format %{ "BA $labl\t! short branch" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ ba_short(*L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_imm); +%} + // Conditional Direct Branch instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{ match(If cmp icc); @@ -9211,6 +9287,536 @@ ins_pipe(br_cc); %} +instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ + match(If cmp icc); + effect(USE labl); + + ins_cost(BRANCH_COST); + format %{ "BP$cmp $icc,$labl" %} + // Prim = bits 24-22, Secnd = bits 31-30 + ins_encode( enc_bp( labl, cmp, icc ) ); + ins_pipe(br_cc); +%} + +instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ + match(If cmp pcc); + effect(USE labl); + + size(8); + ins_cost(BRANCH_COST); + format %{ "BP$cmp $pcc,$labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + + __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(br_cc); +%} + +instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ + match(If cmp fcc); + effect(USE labl); + + size(8); + ins_cost(BRANCH_COST); + format %{ "FBP$cmp $fcc,$labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + + __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(br_fcc); +%} + +instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ + match(CountedLoopEnd cmp icc); + effect(USE labl); + + size(8); + ins_cost(BRANCH_COST); + format %{ "BP$cmp $icc,$labl\t! Loop end" %} + // Prim = bits 24-22, Secnd = bits 31-30 + ins_encode( enc_bp( labl, cmp, icc ) ); + ins_pipe(br_cc); +%} + +instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ + match(CountedLoopEnd cmp icc); + effect(USE labl); + + size(8); + ins_cost(BRANCH_COST); + format %{ "BP$cmp $icc,$labl\t! Loop end" %} + // Prim = bits 24-22, Secnd = bits 31-30 + ins_encode( enc_bp( labl, cmp, icc ) ); + ins_pipe(br_cc); +%} + +// Compare and branch instructions +instruct cmpI_reg_branch(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ + match(If cmp (CmpI op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! int\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpI_imm_branch(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ + match(If cmp (CmpI op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! int\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$constant); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_imm); +%} + +instruct cmpU_reg_branch(cmpOpU cmp, iRegI op1, iRegI op2, label labl, flagsRegU icc) %{ + match(If cmp (CmpU op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! unsigned\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpU_imm_branch(cmpOpU cmp, iRegI op1, immI5 op2, label labl, flagsRegU icc) %{ + match(If cmp (CmpU op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! unsigned\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$constant); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_imm); +%} + +instruct cmpL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{ + match(If cmp (CmpL op1 op2)); + effect(USE labl, KILL xcc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! long\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpL_imm_branch(cmpOp cmp, iRegL op1, immL5 op2, label labl, flagsRegL xcc) %{ + match(If cmp (CmpL op1 op2)); + effect(USE labl, KILL xcc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! long\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$constant); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_imm); +%} + +// Compare Pointers and branch +instruct cmpP_reg_branch(cmpOpP cmp, iRegP op1, iRegP op2, label labl, flagsRegP pcc) %{ + match(If cmp (CmpP op1 op2)); + effect(USE labl, KILL pcc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! ptr\n\t" + "B$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpP_null_branch(cmpOpP cmp, iRegP op1, immP0 null, label labl, flagsRegP pcc) %{ + match(If cmp (CmpP op1 null)); + effect(USE labl, KILL pcc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,0\t! ptr\n\t" + "B$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, G0); + // bpr() is not used here since it has shorter distance. + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpN_reg_branch(cmpOp cmp, iRegN op1, iRegN op2, label labl, flagsReg icc) %{ + match(If cmp (CmpN op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! compressed ptr\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpN_null_branch(cmpOp cmp, iRegN op1, immN0 null, label labl, flagsReg icc) %{ + match(If cmp (CmpN op1 null)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,0\t! compressed ptr\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, G0); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +// Loop back branch +instruct cmpI_reg_branchLoopEnd(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ + match(CountedLoopEnd cmp (CmpI op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! int\n\t" + "BP$cmp $labl\t! Loop end" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpI_imm_branchLoopEnd(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ + match(CountedLoopEnd cmp (CmpI op1 op2)); + effect(USE labl, KILL icc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! int\n\t" + "BP$cmp $labl\t! Loop end" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$constant); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_imm); +%} + +// Short compare and branch instructions +instruct cmpI_reg_branch_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ + match(If cmp (CmpI op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,$op2,$labl\t! int" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpI_imm_branch_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ + match(If cmp (CmpI op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,$op2,$labl\t! int" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_imm); +%} + +instruct cmpU_reg_branch_short(cmpOpU cmp, iRegI op1, iRegI op2, label labl, flagsRegU icc) %{ + match(If cmp (CmpU op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,$op2,$labl\t! unsigned" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, flagsRegU icc) %{ + match(If cmp (CmpU op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,$op2,$labl\t! unsigned" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_imm); +%} + +instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{ + match(If cmp (CmpL op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL xcc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CXB$cmp $op1,$op2,$labl\t! long" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpL_imm_branch_short(cmpOp cmp, iRegL op1, immL5 op2, label labl, flagsRegL xcc) %{ + match(If cmp (CmpL op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL xcc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CXB$cmp $op1,$op2,$labl\t! long" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_imm); +%} + +// Compare Pointers and branch +instruct cmpP_reg_branch_short(cmpOpP cmp, iRegP op1, iRegP op2, label labl, flagsRegP pcc) %{ + match(If cmp (CmpP op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL pcc); + + size(4); + ins_cost(BRANCH_COST); +#ifdef _LP64 + format %{ "CXB$cmp $op1,$op2,$labl\t! ptr" %} +#else + format %{ "CWB$cmp $op1,$op2,$labl\t! ptr" %} +#endif + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpP_null_branch_short(cmpOpP cmp, iRegP op1, immP0 null, label labl, flagsRegP pcc) %{ + match(If cmp (CmpP op1 null)); + predicate(UseCBCond); + effect(USE labl, KILL pcc); + + size(4); + ins_cost(BRANCH_COST); +#ifdef _LP64 + format %{ "CXB$cmp $op1,0,$labl\t! ptr" %} +#else + format %{ "CWB$cmp $op1,0,$labl\t! ptr" %} +#endif + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpN_reg_branch_short(cmpOp cmp, iRegN op1, iRegN op2, label labl, flagsReg icc) %{ + match(If cmp (CmpN op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,op2,$labl\t! compressed ptr" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpN_null_branch_short(cmpOp cmp, iRegN op1, immN0 null, label labl, flagsReg icc) %{ + match(If cmp (CmpN op1 null)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,0,$labl\t! compressed ptr" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, G0, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +// Loop back branch +instruct cmpI_reg_branchLoopEnd_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ + match(CountedLoopEnd cmp (CmpI op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,$op2,$labl\t! Loop end" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpI_imm_branchLoopEnd_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ + match(CountedLoopEnd cmp (CmpI op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL icc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CWB$cmp $op1,$op2,$labl\t! Loop end" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(1); + ins_pipe(cbcond_reg_imm); +%} + // Branch-on-register tests all 64 bits. We assume that values // in 64-bit registers always remains zero or sign extended // unless our code munges the high bits. Interrupts can chop @@ -9251,75 +9857,6 @@ ins_pipe(br_reg); %} -instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ - match(If cmp icc); - effect(USE labl); - - format %{ "BP$cmp $icc,$labl" %} - // Prim = bits 24-22, Secnd = bits 31-30 - ins_encode( enc_bp( labl, cmp, icc ) ); - ins_pipe(br_cc); -%} - -instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ - match(If cmp pcc); - effect(USE labl); - - size(8); - ins_cost(BRANCH_COST); - format %{ "BP$cmp $pcc,$labl" %} - ins_encode %{ - Label* L = $labl$$label; - Assembler::Predict predict_taken = - cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; - - __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); - __ delayed()->nop(); - %} - ins_pipe(br_cc); -%} - -instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ - match(If cmp fcc); - effect(USE labl); - - size(8); - ins_cost(BRANCH_COST); - format %{ "FBP$cmp $fcc,$labl" %} - ins_encode %{ - Label* L = $labl$$label; - Assembler::Predict predict_taken = - cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; - - __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L); - __ delayed()->nop(); - %} - ins_pipe(br_fcc); -%} - -instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ - match(CountedLoopEnd cmp icc); - effect(USE labl); - - size(8); - ins_cost(BRANCH_COST); - format %{ "BP$cmp $icc,$labl\t! Loop end" %} - // Prim = bits 24-22, Secnd = bits 31-30 - ins_encode( enc_bp( labl, cmp, icc ) ); - ins_pipe(br_cc); -%} - -instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ - match(CountedLoopEnd cmp icc); - effect(USE labl); - - size(8); - ins_cost(BRANCH_COST); - format %{ "BP$cmp $icc,$labl\t! Loop end" %} - // Prim = bits 24-22, Secnd = bits 31-30 - ins_encode( enc_bp( labl, cmp, icc ) ); - ins_pipe(br_cc); -%} // ============================================================================ // Long Compare