Mercurial > hg > graal-compiler
comparison src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 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 | bb22629531fa |
children | c124e2e7463e |
comparison
equal
deleted
inserted
replaced
3838:6a991dcb52bb | 3839:3d42f82cd811 |
---|---|
215 #ifdef ASSERT | 215 #ifdef ASSERT |
216 // verify the interpreter's monitor has a non-null object | 216 // verify the interpreter's monitor has a non-null object |
217 { | 217 { |
218 Label L; | 218 Label L; |
219 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); | 219 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); |
220 __ cmp(G0, O7); | 220 __ cmp_and_br_short(O7, G0, Assembler::notEqual, Assembler::pt, L); |
221 __ br(Assembler::notEqual, false, Assembler::pt, L); | |
222 __ delayed()->nop(); | |
223 __ stop("locked object is NULL"); | 221 __ stop("locked object is NULL"); |
224 __ bind(L); | 222 __ bind(L); |
225 } | 223 } |
226 #endif // ASSERT | 224 #endif // ASSERT |
227 // Copy the lock field into the compiled activation. | 225 // Copy the lock field into the compiled activation. |
2094 | 2092 |
2095 if (copyfunc_addr != NULL) { | 2093 if (copyfunc_addr != NULL) { |
2096 __ xor3(O0, -1, tmp); | 2094 __ xor3(O0, -1, tmp); |
2097 __ sub(length, tmp, length); | 2095 __ sub(length, tmp, length); |
2098 __ add(src_pos, tmp, src_pos); | 2096 __ add(src_pos, tmp, src_pos); |
2099 __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry()); | 2097 __ cmp_zero_and_br(Assembler::less, O0, *stub->entry()); |
2100 __ delayed()->add(dst_pos, tmp, dst_pos); | 2098 __ delayed()->add(dst_pos, tmp, dst_pos); |
2101 } else { | 2099 } else { |
2102 __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry()); | 2100 __ cmp_zero_and_br(Assembler::less, O0, *stub->entry()); |
2103 __ delayed()->nop(); | 2101 __ delayed()->nop(); |
2104 } | 2102 } |
2105 __ bind(*stub->continuation()); | 2103 __ bind(*stub->continuation()); |
2106 return; | 2104 return; |
2107 } | 2105 } |
2121 __ delayed()->nop(); | 2119 __ delayed()->nop(); |
2122 } | 2120 } |
2123 | 2121 |
2124 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { | 2122 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { |
2125 // test src_pos register | 2123 // test src_pos register |
2126 __ tst(src_pos); | 2124 __ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry()); |
2127 __ br(Assembler::less, false, Assembler::pn, *stub->entry()); | |
2128 __ delayed()->nop(); | 2125 __ delayed()->nop(); |
2129 } | 2126 } |
2130 | 2127 |
2131 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { | 2128 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { |
2132 // test dst_pos register | 2129 // test dst_pos register |
2133 __ tst(dst_pos); | 2130 __ cmp_zero_and_br(Assembler::less, dst_pos, *stub->entry()); |
2134 __ br(Assembler::less, false, Assembler::pn, *stub->entry()); | |
2135 __ delayed()->nop(); | 2131 __ delayed()->nop(); |
2136 } | 2132 } |
2137 | 2133 |
2138 if (flags & LIR_OpArrayCopy::length_positive_check) { | 2134 if (flags & LIR_OpArrayCopy::length_positive_check) { |
2139 // make sure length isn't negative | 2135 // make sure length isn't negative |
2140 __ tst(length); | 2136 __ cmp_zero_and_br(Assembler::less, length, *stub->entry()); |
2141 __ br(Assembler::less, false, Assembler::pn, *stub->entry()); | |
2142 __ delayed()->nop(); | 2137 __ delayed()->nop(); |
2143 } | 2138 } |
2144 | 2139 |
2145 if (flags & LIR_OpArrayCopy::src_range_check) { | 2140 if (flags & LIR_OpArrayCopy::src_range_check) { |
2146 __ ld(src, arrayOopDesc::length_offset_in_bytes(), tmp2); | 2141 __ ld(src, arrayOopDesc::length_offset_in_bytes(), tmp2); |
2259 __ call_VM_leaf(tmp, copyfunc_addr); | 2254 __ call_VM_leaf(tmp, copyfunc_addr); |
2260 | 2255 |
2261 #ifndef PRODUCT | 2256 #ifndef PRODUCT |
2262 if (PrintC1Statistics) { | 2257 if (PrintC1Statistics) { |
2263 Label failed; | 2258 Label failed; |
2264 __ br_notnull(O0, false, Assembler::pn, failed); | 2259 __ br_notnull_short(O0, Assembler::pn, failed); |
2265 __ delayed()->nop(); | |
2266 __ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3); | 2260 __ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3); |
2267 __ bind(failed); | 2261 __ bind(failed); |
2268 } | 2262 } |
2269 #endif | 2263 #endif |
2270 | 2264 |
2312 if (basic_type != T_OBJECT) { | 2306 if (basic_type != T_OBJECT) { |
2313 __ cmp(tmp, tmp2); | 2307 __ cmp(tmp, tmp2); |
2314 __ br(Assembler::notEqual, false, Assembler::pn, halt); | 2308 __ br(Assembler::notEqual, false, Assembler::pn, halt); |
2315 // load the raw value of the src klass. | 2309 // load the raw value of the src klass. |
2316 __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); | 2310 __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); |
2317 __ cmp(tmp, tmp2); | 2311 __ cmp_and_br_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok); |
2318 __ br(Assembler::equal, false, Assembler::pn, known_ok); | |
2319 __ delayed()->nop(); | |
2320 } else { | 2312 } else { |
2321 __ cmp(tmp, tmp2); | 2313 __ cmp(tmp, tmp2); |
2322 __ br(Assembler::equal, false, Assembler::pn, known_ok); | 2314 __ br(Assembler::equal, false, Assembler::pn, known_ok); |
2323 __ delayed()->cmp(src, dst); | 2315 __ delayed()->cmp(src, dst); |
2324 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | 2316 __ brx(Assembler::equal, false, Assembler::pn, known_ok); |
2328 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); | 2320 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); |
2329 if (basic_type != T_OBJECT) { | 2321 if (basic_type != T_OBJECT) { |
2330 __ cmp(tmp, tmp2); | 2322 __ cmp(tmp, tmp2); |
2331 __ brx(Assembler::notEqual, false, Assembler::pn, halt); | 2323 __ brx(Assembler::notEqual, false, Assembler::pn, halt); |
2332 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); | 2324 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); |
2333 __ cmp(tmp, tmp2); | 2325 __ cmp_and_brx_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok); |
2334 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2335 __ delayed()->nop(); | |
2336 } else { | 2326 } else { |
2337 __ cmp(tmp, tmp2); | 2327 __ cmp(tmp, tmp2); |
2338 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | 2328 __ brx(Assembler::equal, false, Assembler::pn, known_ok); |
2339 __ delayed()->cmp(src, dst); | 2329 __ delayed()->cmp(src, dst); |
2340 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | 2330 __ brx(Assembler::equal, false, Assembler::pn, known_ok); |
2528 // See if the receiver is receiver[n]. | 2518 // See if the receiver is receiver[n]. |
2529 Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - | 2519 Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - |
2530 mdo_offset_bias); | 2520 mdo_offset_bias); |
2531 __ ld_ptr(receiver_addr, tmp1); | 2521 __ ld_ptr(receiver_addr, tmp1); |
2532 __ verify_oop(tmp1); | 2522 __ verify_oop(tmp1); |
2533 __ cmp(recv, tmp1); | 2523 __ cmp_and_brx_short(recv, tmp1, Assembler::notEqual, Assembler::pt, next_test); |
2534 __ brx(Assembler::notEqual, false, Assembler::pt, next_test); | |
2535 __ delayed()->nop(); | |
2536 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - | 2524 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - |
2537 mdo_offset_bias); | 2525 mdo_offset_bias); |
2538 __ ld_ptr(data_addr, tmp1); | 2526 __ ld_ptr(data_addr, tmp1); |
2539 __ add(tmp1, DataLayout::counter_increment, tmp1); | 2527 __ add(tmp1, DataLayout::counter_increment, tmp1); |
2540 __ st_ptr(tmp1, data_addr); | 2528 __ st_ptr(tmp1, data_addr); |
2541 __ ba(false, *update_done); | 2529 __ ba(*update_done); |
2542 __ delayed()->nop(); | 2530 __ delayed()->nop(); |
2543 __ bind(next_test); | 2531 __ bind(next_test); |
2544 } | 2532 } |
2545 | 2533 |
2546 // Didn't find receiver; find next empty slot and fill it in | 2534 // Didn't find receiver; find next empty slot and fill it in |
2547 for (i = 0; i < VirtualCallData::row_limit(); i++) { | 2535 for (i = 0; i < VirtualCallData::row_limit(); i++) { |
2548 Label next_test; | 2536 Label next_test; |
2549 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - | 2537 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - |
2550 mdo_offset_bias); | 2538 mdo_offset_bias); |
2551 __ ld_ptr(recv_addr, tmp1); | 2539 __ ld_ptr(recv_addr, tmp1); |
2552 __ br_notnull(tmp1, false, Assembler::pt, next_test); | 2540 __ br_notnull_short(tmp1, Assembler::pt, next_test); |
2553 __ delayed()->nop(); | |
2554 __ st_ptr(recv, recv_addr); | 2541 __ st_ptr(recv, recv_addr); |
2555 __ set(DataLayout::counter_increment, tmp1); | 2542 __ set(DataLayout::counter_increment, tmp1); |
2556 __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - | 2543 __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - |
2557 mdo_offset_bias); | 2544 mdo_offset_bias); |
2558 __ ba(false, *update_done); | 2545 __ ba(*update_done); |
2559 __ delayed()->nop(); | 2546 __ delayed()->nop(); |
2560 __ bind(next_test); | 2547 __ bind(next_test); |
2561 } | 2548 } |
2562 } | 2549 } |
2563 | 2550 |
2599 ciMethod* method = op->profiled_method(); | 2586 ciMethod* method = op->profiled_method(); |
2600 assert(method != NULL, "Should have method"); | 2587 assert(method != NULL, "Should have method"); |
2601 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); | 2588 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); |
2602 | 2589 |
2603 Label not_null; | 2590 Label not_null; |
2604 __ br_notnull(obj, false, Assembler::pn, not_null); | 2591 __ br_notnull_short(obj, Assembler::pn, not_null); |
2605 __ delayed()->nop(); | |
2606 Register mdo = k_RInfo; | 2592 Register mdo = k_RInfo; |
2607 Register data_val = Rtmp1; | 2593 Register data_val = Rtmp1; |
2608 jobject2reg(md->constant_encoding(), mdo); | 2594 jobject2reg(md->constant_encoding(), mdo); |
2609 if (mdo_offset_bias > 0) { | 2595 if (mdo_offset_bias > 0) { |
2610 __ set(mdo_offset_bias, data_val); | 2596 __ set(mdo_offset_bias, data_val); |
2612 } | 2598 } |
2613 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); | 2599 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); |
2614 __ ldub(flags_addr, data_val); | 2600 __ ldub(flags_addr, data_val); |
2615 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); | 2601 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); |
2616 __ stb(data_val, flags_addr); | 2602 __ stb(data_val, flags_addr); |
2617 __ ba(false, *obj_is_null); | 2603 __ ba(*obj_is_null); |
2618 __ delayed()->nop(); | 2604 __ delayed()->nop(); |
2619 __ bind(not_null); | 2605 __ bind(not_null); |
2620 } else { | 2606 } else { |
2621 __ br_null(obj, false, Assembler::pn, *obj_is_null); | 2607 __ br_null(obj, false, Assembler::pn, *obj_is_null); |
2622 __ delayed()->nop(); | 2608 __ delayed()->nop(); |
2680 __ add(mdo, tmp1, mdo); | 2666 __ add(mdo, tmp1, mdo); |
2681 } | 2667 } |
2682 __ load_klass(obj, recv); | 2668 __ load_klass(obj, recv); |
2683 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); | 2669 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); |
2684 // Jump over the failure case | 2670 // Jump over the failure case |
2685 __ ba(false, *success); | 2671 __ ba(*success); |
2686 __ delayed()->nop(); | 2672 __ delayed()->nop(); |
2687 // Cast failure case | 2673 // Cast failure case |
2688 __ bind(profile_cast_failure); | 2674 __ bind(profile_cast_failure); |
2689 jobject2reg(md->constant_encoding(), mdo); | 2675 jobject2reg(md->constant_encoding(), mdo); |
2690 if (mdo_offset_bias > 0) { | 2676 if (mdo_offset_bias > 0) { |
2693 } | 2679 } |
2694 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); | 2680 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); |
2695 __ ld_ptr(data_addr, tmp1); | 2681 __ ld_ptr(data_addr, tmp1); |
2696 __ sub(tmp1, DataLayout::counter_increment, tmp1); | 2682 __ sub(tmp1, DataLayout::counter_increment, tmp1); |
2697 __ st_ptr(tmp1, data_addr); | 2683 __ st_ptr(tmp1, data_addr); |
2698 __ ba(false, *failure); | 2684 __ ba(*failure); |
2699 __ delayed()->nop(); | 2685 __ delayed()->nop(); |
2700 } | 2686 } |
2701 __ ba(false, *success); | 2687 __ ba(*success); |
2702 __ delayed()->nop(); | 2688 __ delayed()->nop(); |
2703 } | 2689 } |
2704 | 2690 |
2705 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { | 2691 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { |
2706 LIR_Code code = op->code(); | 2692 LIR_Code code = op->code(); |
2726 Label *success_target = op->should_profile() ? &profile_cast_success : &done; | 2712 Label *success_target = op->should_profile() ? &profile_cast_success : &done; |
2727 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); | 2713 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); |
2728 | 2714 |
2729 if (op->should_profile()) { | 2715 if (op->should_profile()) { |
2730 Label not_null; | 2716 Label not_null; |
2731 __ br_notnull(value, false, Assembler::pn, not_null); | 2717 __ br_notnull_short(value, Assembler::pn, not_null); |
2732 __ delayed()->nop(); | |
2733 Register mdo = k_RInfo; | 2718 Register mdo = k_RInfo; |
2734 Register data_val = Rtmp1; | 2719 Register data_val = Rtmp1; |
2735 jobject2reg(md->constant_encoding(), mdo); | 2720 jobject2reg(md->constant_encoding(), mdo); |
2736 if (mdo_offset_bias > 0) { | 2721 if (mdo_offset_bias > 0) { |
2737 __ set(mdo_offset_bias, data_val); | 2722 __ set(mdo_offset_bias, data_val); |
2739 } | 2724 } |
2740 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); | 2725 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); |
2741 __ ldub(flags_addr, data_val); | 2726 __ ldub(flags_addr, data_val); |
2742 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); | 2727 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); |
2743 __ stb(data_val, flags_addr); | 2728 __ stb(data_val, flags_addr); |
2744 __ ba(false, done); | 2729 __ ba_short(done); |
2745 __ delayed()->nop(); | |
2746 __ bind(not_null); | 2730 __ bind(not_null); |
2747 } else { | 2731 } else { |
2748 __ br_null(value, false, Assembler::pn, done); | 2732 __ br_null_short(value, Assembler::pn, done); |
2749 __ delayed()->nop(); | |
2750 } | 2733 } |
2751 add_debug_info_for_null_check_here(op->info_for_exception()); | 2734 add_debug_info_for_null_check_here(op->info_for_exception()); |
2752 __ load_klass(array, k_RInfo); | 2735 __ load_klass(array, k_RInfo); |
2753 __ load_klass(value, klass_RInfo); | 2736 __ load_klass(value, klass_RInfo); |
2754 | 2737 |
2775 __ set(mdo_offset_bias, tmp1); | 2758 __ set(mdo_offset_bias, tmp1); |
2776 __ add(mdo, tmp1, mdo); | 2759 __ add(mdo, tmp1, mdo); |
2777 } | 2760 } |
2778 __ load_klass(value, recv); | 2761 __ load_klass(value, recv); |
2779 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); | 2762 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); |
2780 __ ba(false, done); | 2763 __ ba_short(done); |
2781 __ delayed()->nop(); | |
2782 // Cast failure case | 2764 // Cast failure case |
2783 __ bind(profile_cast_failure); | 2765 __ bind(profile_cast_failure); |
2784 jobject2reg(md->constant_encoding(), mdo); | 2766 jobject2reg(md->constant_encoding(), mdo); |
2785 if (mdo_offset_bias > 0) { | 2767 if (mdo_offset_bias > 0) { |
2786 __ set(mdo_offset_bias, tmp1); | 2768 __ set(mdo_offset_bias, tmp1); |
2788 } | 2770 } |
2789 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); | 2771 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); |
2790 __ ld_ptr(data_addr, tmp1); | 2772 __ ld_ptr(data_addr, tmp1); |
2791 __ sub(tmp1, DataLayout::counter_increment, tmp1); | 2773 __ sub(tmp1, DataLayout::counter_increment, tmp1); |
2792 __ st_ptr(tmp1, data_addr); | 2774 __ st_ptr(tmp1, data_addr); |
2793 __ ba(false, *stub->entry()); | 2775 __ ba(*stub->entry()); |
2794 __ delayed()->nop(); | 2776 __ delayed()->nop(); |
2795 } | 2777 } |
2796 __ bind(done); | 2778 __ bind(done); |
2797 } else if (code == lir_checkcast) { | 2779 } else if (code == lir_checkcast) { |
2798 Register obj = op->object()->as_register(); | 2780 Register obj = op->object()->as_register(); |
2806 Register dst = op->result_opr()->as_register(); | 2788 Register dst = op->result_opr()->as_register(); |
2807 Label success, failure, done; | 2789 Label success, failure, done; |
2808 emit_typecheck_helper(op, &success, &failure, &failure); | 2790 emit_typecheck_helper(op, &success, &failure, &failure); |
2809 __ bind(failure); | 2791 __ bind(failure); |
2810 __ set(0, dst); | 2792 __ set(0, dst); |
2811 __ ba(false, done); | 2793 __ ba_short(done); |
2812 __ delayed()->nop(); | |
2813 __ bind(success); | 2794 __ bind(success); |
2814 __ set(1, dst); | 2795 __ set(1, dst); |
2815 __ bind(done); | 2796 __ bind(done); |
2816 } else { | 2797 } else { |
2817 ShouldNotReachHere(); | 2798 ShouldNotReachHere(); |