Mercurial > hg > graal-compiler
comparison src/cpu/sparc/vm/sparc.ad @ 3839:3d42f82cd811
7063628: Use cbcond on T4
Summary: Add new short branch instruction to Hotspot sparc assembler.
Reviewed-by: never, twisti, jrose
author | kvn |
---|---|
date | Thu, 21 Jul 2011 11:25:07 -0700 |
parents | faa472957b38 |
children | c7b60b601eb4 |
comparison
equal
deleted
inserted
replaced
3838:6a991dcb52bb | 3839:3d42f82cd811 |
---|---|
1691 } | 1691 } |
1692 #endif | 1692 #endif |
1693 | 1693 |
1694 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | 1694 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
1695 MacroAssembler _masm(&cbuf); | 1695 MacroAssembler _masm(&cbuf); |
1696 Label L; | |
1697 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); | 1696 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); |
1698 Register temp_reg = G3; | 1697 Register temp_reg = G3; |
1699 assert( G5_ic_reg != temp_reg, "conflicting registers" ); | 1698 assert( G5_ic_reg != temp_reg, "conflicting registers" ); |
1700 | 1699 |
1701 // Load klass from receiver | 1700 // Load klass from receiver |
2313 MacroAssembler _masm(&cbuf); | 2312 MacroAssembler _masm(&cbuf); |
2314 __ call(StubRoutines::Sparc::partial_subtype_check(), relocInfo::runtime_call_type); | 2313 __ call(StubRoutines::Sparc::partial_subtype_check(), relocInfo::runtime_call_type); |
2315 __ delayed()->nop(); | 2314 __ delayed()->nop(); |
2316 %} | 2315 %} |
2317 | 2316 |
2318 enc_class enc_bp( Label labl, cmpOp cmp, flagsReg cc ) %{ | 2317 enc_class enc_bp( label labl, cmpOp cmp, flagsReg cc ) %{ |
2319 MacroAssembler _masm(&cbuf); | 2318 MacroAssembler _masm(&cbuf); |
2320 Label &L = *($labl$$label); | 2319 Label* L = $labl$$label; |
2321 Assembler::Predict predict_taken = | 2320 Assembler::Predict predict_taken = |
2322 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | 2321 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; |
2323 | 2322 |
2324 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, L); | 2323 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); |
2325 __ delayed()->nop(); | 2324 __ delayed()->nop(); |
2326 %} | 2325 %} |
2327 | 2326 |
2328 enc_class enc_bpl( Label labl, cmpOp cmp, flagsRegL cc ) %{ | 2327 enc_class enc_bpr( label labl, cmpOp_reg cmp, iRegI op1 ) %{ |
2329 MacroAssembler _masm(&cbuf); | 2328 MacroAssembler _masm(&cbuf); |
2330 Label &L = *($labl$$label); | 2329 Label* L = $labl$$label; |
2331 Assembler::Predict predict_taken = | 2330 Assembler::Predict predict_taken = |
2332 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | 2331 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; |
2333 | 2332 |
2334 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, L); | 2333 __ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), *L); |
2335 __ delayed()->nop(); | |
2336 %} | |
2337 | |
2338 enc_class enc_bpx( Label labl, cmpOp cmp, flagsRegP cc ) %{ | |
2339 MacroAssembler _masm(&cbuf); | |
2340 Label &L = *($labl$$label); | |
2341 Assembler::Predict predict_taken = | |
2342 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2343 | |
2344 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, L); | |
2345 __ delayed()->nop(); | |
2346 %} | |
2347 | |
2348 enc_class enc_fbp( Label labl, cmpOpF cmp, flagsRegF cc ) %{ | |
2349 MacroAssembler _masm(&cbuf); | |
2350 Label &L = *($labl$$label); | |
2351 Assembler::Predict predict_taken = | |
2352 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2353 | |
2354 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L); | |
2355 __ delayed()->nop(); | |
2356 %} | |
2357 | |
2358 enc_class enc_ba( Label labl ) %{ | |
2359 MacroAssembler _masm(&cbuf); | |
2360 Label &L = *($labl$$label); | |
2361 __ ba(false, L); | |
2362 __ delayed()->nop(); | |
2363 %} | |
2364 | |
2365 enc_class enc_bpr( Label labl, cmpOp_reg cmp, iRegI op1 ) %{ | |
2366 MacroAssembler _masm(&cbuf); | |
2367 Label &L = *$labl$$label; | |
2368 Assembler::Predict predict_taken = | |
2369 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2370 | |
2371 __ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), L); | |
2372 __ delayed()->nop(); | 2334 __ delayed()->nop(); |
2373 %} | 2335 %} |
2374 | 2336 |
2375 enc_class enc_cmov_reg( cmpOp cmp, iRegI dst, iRegI src, immI pcc) %{ | 2337 enc_class enc_cmov_reg( cmpOp cmp, iRegI dst, iRegI src, immI pcc) %{ |
2376 int op = (Assembler::arith_op << 30) | | 2338 int op = (Assembler::arith_op << 30) | |
2984 | 2946 |
2985 __ cmp(str1_reg, str2_reg); //same char[] ? | 2947 __ cmp(str1_reg, str2_reg); //same char[] ? |
2986 __ brx(Assembler::equal, true, Assembler::pn, Ldone); | 2948 __ brx(Assembler::equal, true, Assembler::pn, Ldone); |
2987 __ delayed()->add(G0, 1, result_reg); | 2949 __ delayed()->add(G0, 1, result_reg); |
2988 | 2950 |
2989 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone); | 2951 __ cmp_zero_and_br(Assembler::zero, cnt_reg, Ldone, true, Assembler::pn); |
2990 __ delayed()->add(G0, 1, result_reg); // count == 0 | 2952 __ delayed()->add(G0, 1, result_reg); // count == 0 |
2991 | 2953 |
2992 //rename registers | 2954 //rename registers |
2993 Register limit_reg = cnt_reg; | 2955 Register limit_reg = cnt_reg; |
2994 Register chr1_reg = result_reg; | 2956 Register chr1_reg = result_reg; |
3004 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count | 2966 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count |
3005 | 2967 |
3006 // Compare char[] arrays aligned to 4 bytes. | 2968 // Compare char[] arrays aligned to 4 bytes. |
3007 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg, | 2969 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg, |
3008 chr1_reg, chr2_reg, Ldone); | 2970 chr1_reg, chr2_reg, Ldone); |
3009 __ ba(false,Ldone); | 2971 __ ba(Ldone); |
3010 __ delayed()->add(G0, 1, result_reg); | 2972 __ delayed()->add(G0, 1, result_reg); |
3011 | 2973 |
3012 // char by char compare | 2974 // char by char compare |
3013 __ bind(Lchar); | 2975 __ bind(Lchar); |
3014 __ add(str1_reg, limit_reg, str1_reg); | 2976 __ add(str1_reg, limit_reg, str1_reg); |
3063 // return false if the two arrays are not equal length | 3025 // return false if the two arrays are not equal length |
3064 __ cmp(tmp1_reg, tmp2_reg); | 3026 __ cmp(tmp1_reg, tmp2_reg); |
3065 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); | 3027 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); |
3066 __ delayed()->mov(G0, result_reg); // not equal | 3028 __ delayed()->mov(G0, result_reg); // not equal |
3067 | 3029 |
3068 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone); | 3030 __ cmp_zero_and_br(Assembler::zero, tmp1_reg, Ldone, true, Assembler::pn); |
3069 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal | 3031 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal |
3070 | 3032 |
3071 // load array addresses | 3033 // load array addresses |
3072 __ add(ary1_reg, base_offset, ary1_reg); | 3034 __ add(ary1_reg, base_offset, ary1_reg); |
3073 __ add(ary2_reg, base_offset, ary2_reg); | 3035 __ add(ary2_reg, base_offset, ary2_reg); |
9230 effect(USE labl); | 9192 effect(USE labl); |
9231 | 9193 |
9232 size(8); | 9194 size(8); |
9233 ins_cost(BRANCH_COST); | 9195 ins_cost(BRANCH_COST); |
9234 format %{ "BA $labl" %} | 9196 format %{ "BA $labl" %} |
9235 // Prim = bits 24-22, Secnd = bits 31-30, Tert = cond | 9197 ins_encode %{ |
9236 opcode(Assembler::br_op2, Assembler::branch_op, Assembler::always); | 9198 Label* L = $labl$$label; |
9237 ins_encode( enc_ba( labl ) ); | 9199 __ ba(*L); |
9200 __ delayed()->nop(); | |
9201 %} | |
9238 ins_pc_relative(1); | 9202 ins_pc_relative(1); |
9239 ins_pipe(br); | 9203 ins_pipe(br); |
9240 %} | 9204 %} |
9241 | 9205 |
9242 // Conditional Direct Branch | 9206 // Conditional Direct Branch |
9312 effect(USE labl); | 9276 effect(USE labl); |
9313 | 9277 |
9314 size(8); | 9278 size(8); |
9315 ins_cost(BRANCH_COST); | 9279 ins_cost(BRANCH_COST); |
9316 format %{ "BP$cmp $pcc,$labl" %} | 9280 format %{ "BP$cmp $pcc,$labl" %} |
9317 // Prim = bits 24-22, Secnd = bits 31-30 | 9281 ins_encode %{ |
9318 ins_encode( enc_bpx( labl, cmp, pcc ) ); | 9282 Label* L = $labl$$label; |
9283 Assembler::Predict predict_taken = | |
9284 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9285 | |
9286 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); | |
9287 __ delayed()->nop(); | |
9288 %} | |
9319 ins_pc_relative(1); | 9289 ins_pc_relative(1); |
9320 ins_pipe(br_cc); | 9290 ins_pipe(br_cc); |
9321 %} | 9291 %} |
9322 | 9292 |
9323 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ | 9293 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ |
9325 effect(USE labl); | 9295 effect(USE labl); |
9326 | 9296 |
9327 size(8); | 9297 size(8); |
9328 ins_cost(BRANCH_COST); | 9298 ins_cost(BRANCH_COST); |
9329 format %{ "FBP$cmp $fcc,$labl" %} | 9299 format %{ "FBP$cmp $fcc,$labl" %} |
9330 // Prim = bits 24-22, Secnd = bits 31-30 | 9300 ins_encode %{ |
9331 ins_encode( enc_fbp( labl, cmp, fcc ) ); | 9301 Label* L = $labl$$label; |
9302 Assembler::Predict predict_taken = | |
9303 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9304 | |
9305 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L); | |
9306 __ delayed()->nop(); | |
9307 %} | |
9332 ins_pc_relative(1); | 9308 ins_pc_relative(1); |
9333 ins_pipe(br_fcc); | 9309 ins_pipe(br_fcc); |
9334 %} | 9310 %} |
9335 | 9311 |
9336 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ | 9312 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ |
9385 effect(USE labl); | 9361 effect(USE labl); |
9386 | 9362 |
9387 size(8); | 9363 size(8); |
9388 ins_cost(BRANCH_COST); | 9364 ins_cost(BRANCH_COST); |
9389 format %{ "BP$cmp $xcc,$labl" %} | 9365 format %{ "BP$cmp $xcc,$labl" %} |
9390 // Prim = bits 24-22, Secnd = bits 31-30 | 9366 ins_encode %{ |
9391 ins_encode( enc_bpl( labl, cmp, xcc ) ); | 9367 Label* L = $labl$$label; |
9368 Assembler::Predict predict_taken = | |
9369 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9370 | |
9371 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); | |
9372 __ delayed()->nop(); | |
9373 %} | |
9392 ins_pc_relative(1); | 9374 ins_pc_relative(1); |
9393 ins_pipe(br_cc); | 9375 ins_pipe(br_cc); |
9394 %} | 9376 %} |
9395 | 9377 |
9396 // Manifest a CmpL3 result in an integer register. Very painful. | 9378 // Manifest a CmpL3 result in an integer register. Very painful. |
9705 match(Set pcc (FastLock object box)); | 9687 match(Set pcc (FastLock object box)); |
9706 | 9688 |
9707 effect(KILL scratch, TEMP scratch2); | 9689 effect(KILL scratch, TEMP scratch2); |
9708 ins_cost(100); | 9690 ins_cost(100); |
9709 | 9691 |
9710 size(4*112); // conservative overestimation ... | |
9711 format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %} | 9692 format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %} |
9712 ins_encode( Fast_Lock(object, box, scratch, scratch2) ); | 9693 ins_encode( Fast_Lock(object, box, scratch, scratch2) ); |
9713 ins_pipe(long_memory_op); | 9694 ins_pipe(long_memory_op); |
9714 %} | 9695 %} |
9715 | 9696 |
9717 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ | 9698 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ |
9718 match(Set pcc (FastUnlock object box)); | 9699 match(Set pcc (FastUnlock object box)); |
9719 effect(KILL scratch, TEMP scratch2); | 9700 effect(KILL scratch, TEMP scratch2); |
9720 ins_cost(100); | 9701 ins_cost(100); |
9721 | 9702 |
9722 size(4*120); // conservative overestimation ... | |
9723 format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %} | 9703 format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %} |
9724 ins_encode( Fast_Unlock(object, box, scratch, scratch2) ); | 9704 ins_encode( Fast_Unlock(object, box, scratch, scratch2) ); |
9725 ins_pipe(long_memory_op); | 9705 ins_pipe(long_memory_op); |
9726 %} | 9706 %} |
9727 | 9707 |