2632 #endif |
2632 #endif |
2633 |
2633 |
2634 if (offset != 0) |
2634 if (offset != 0) |
2635 add(tmp, offset, tmp); |
2635 add(tmp, offset, tmp); |
2636 |
2636 |
2637 return RegisterConstant(tmp); |
2637 return RegisterOrConstant(tmp); |
2638 } |
2638 } |
2639 |
2639 |
2640 |
2640 |
2641 void MacroAssembler::regcon_inc_ptr( RegisterConstant& dest, RegisterConstant src, Register temp ) { |
2641 void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) { |
2642 assert(dest.register_or_noreg() != G0, "lost side effect"); |
2642 assert(dest.register_or_noreg() != G0, "lost side effect"); |
2643 if ((src.is_constant() && src.as_constant() == 0) || |
2643 if ((src.is_constant() && src.as_constant() == 0) || |
2644 (src.is_register() && src.as_register() == G0)) { |
2644 (src.is_register() && src.as_register() == G0)) { |
2645 // do nothing |
2645 // do nothing |
2646 } else if (dest.is_register()) { |
2646 } else if (dest.is_register()) { |
2647 add(dest.as_register(), ensure_rs2(src, temp), dest.as_register()); |
2647 add(dest.as_register(), ensure_rs2(src, temp), dest.as_register()); |
2648 } else if (src.is_constant()) { |
2648 } else if (src.is_constant()) { |
2649 intptr_t res = dest.as_constant() + src.as_constant(); |
2649 intptr_t res = dest.as_constant() + src.as_constant(); |
2650 dest = RegisterConstant(res); // side effect seen by caller |
2650 dest = RegisterOrConstant(res); // side effect seen by caller |
2651 } else { |
2651 } else { |
2652 assert(temp != noreg, "cannot handle constant += register"); |
2652 assert(temp != noreg, "cannot handle constant += register"); |
2653 add(src.as_register(), ensure_rs2(dest, temp), temp); |
2653 add(src.as_register(), ensure_rs2(dest, temp), temp); |
2654 dest = RegisterConstant(temp); // side effect seen by caller |
2654 dest = RegisterOrConstant(temp); // side effect seen by caller |
2655 } |
2655 } |
2656 } |
2656 } |
2657 |
2657 |
2658 void MacroAssembler::regcon_sll_ptr( RegisterConstant& dest, RegisterConstant src, Register temp ) { |
2658 void MacroAssembler::regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) { |
2659 assert(dest.register_or_noreg() != G0, "lost side effect"); |
2659 assert(dest.register_or_noreg() != G0, "lost side effect"); |
2660 if (!is_simm13(src.constant_or_zero())) |
2660 if (!is_simm13(src.constant_or_zero())) |
2661 src = (src.as_constant() & 0xFF); |
2661 src = (src.as_constant() & 0xFF); |
2662 if ((src.is_constant() && src.as_constant() == 0) || |
2662 if ((src.is_constant() && src.as_constant() == 0) || |
2663 (src.is_register() && src.as_register() == G0)) { |
2663 (src.is_register() && src.as_register() == G0)) { |
2664 // do nothing |
2664 // do nothing |
2665 } else if (dest.is_register()) { |
2665 } else if (dest.is_register()) { |
2666 sll_ptr(dest.as_register(), src, dest.as_register()); |
2666 sll_ptr(dest.as_register(), src, dest.as_register()); |
2667 } else if (src.is_constant()) { |
2667 } else if (src.is_constant()) { |
2668 intptr_t res = dest.as_constant() << src.as_constant(); |
2668 intptr_t res = dest.as_constant() << src.as_constant(); |
2669 dest = RegisterConstant(res); // side effect seen by caller |
2669 dest = RegisterOrConstant(res); // side effect seen by caller |
2670 } else { |
2670 } else { |
2671 assert(temp != noreg, "cannot handle constant <<= register"); |
2671 assert(temp != noreg, "cannot handle constant <<= register"); |
2672 set(dest.as_constant(), temp); |
2672 set(dest.as_constant(), temp); |
2673 sll_ptr(temp, src, temp); |
2673 sll_ptr(temp, src, temp); |
2674 dest = RegisterConstant(temp); // side effect seen by caller |
2674 dest = RegisterOrConstant(temp); // side effect seen by caller |
2675 } |
2675 } |
2676 } |
2676 } |
2677 |
2677 |
2678 |
2678 |
2679 // Look up the method for a megamorphic invokeinterface call. |
2679 // Look up the method for a megamorphic invokeinterface call. |
2681 // The receiver klass is in recv_klass. |
2681 // The receiver klass is in recv_klass. |
2682 // On success, the result will be in method_result, and execution falls through. |
2682 // On success, the result will be in method_result, and execution falls through. |
2683 // On failure, execution transfers to the given label. |
2683 // On failure, execution transfers to the given label. |
2684 void MacroAssembler::lookup_interface_method(Register recv_klass, |
2684 void MacroAssembler::lookup_interface_method(Register recv_klass, |
2685 Register intf_klass, |
2685 Register intf_klass, |
2686 RegisterConstant itable_index, |
2686 RegisterOrConstant itable_index, |
2687 Register method_result, |
2687 Register method_result, |
2688 Register scan_temp, |
2688 Register scan_temp, |
2689 Register sethi_temp, |
2689 Register sethi_temp, |
2690 Label& L_no_such_interface) { |
2690 Label& L_no_such_interface) { |
2691 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); |
2691 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); |
2718 and3(scan_temp, -round_to_unit, scan_temp); |
2718 and3(scan_temp, -round_to_unit, scan_temp); |
2719 } |
2719 } |
2720 add(recv_klass, scan_temp, scan_temp); |
2720 add(recv_klass, scan_temp, scan_temp); |
2721 |
2721 |
2722 // Adjust recv_klass by scaled itable_index, so we can free itable_index. |
2722 // Adjust recv_klass by scaled itable_index, so we can free itable_index. |
2723 RegisterConstant itable_offset = itable_index; |
2723 RegisterOrConstant itable_offset = itable_index; |
2724 regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize)); |
2724 regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize)); |
2725 regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes()); |
2725 regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes()); |
2726 add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass); |
2726 add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass); |
2727 |
2727 |
2728 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { |
2728 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { |
2865 |
2865 |
2866 // Check the supertype display: |
2866 // Check the supertype display: |
2867 if (must_load_sco) { |
2867 if (must_load_sco) { |
2868 // The super check offset is always positive... |
2868 // The super check offset is always positive... |
2869 lduw(super_klass, sco_offset, temp2_reg); |
2869 lduw(super_klass, sco_offset, temp2_reg); |
2870 super_check_offset = RegisterConstant(temp2_reg); |
2870 super_check_offset = RegisterOrConstant(temp2_reg); |
2871 } |
2871 } |
2872 ld_ptr(sub_klass, super_check_offset, temp_reg); |
2872 ld_ptr(sub_klass, super_check_offset, temp_reg); |
2873 cmp(super_klass, temp_reg); |
2873 cmp(super_klass, temp_reg); |
2874 |
2874 |
2875 // This check has worked decisively for primary supers. |
2875 // This check has worked decisively for primary supers. |
4470 bs->kind() == BarrierSet::CardTableExtension, "wrong barrier"); |
4470 bs->kind() == BarrierSet::CardTableExtension, "wrong barrier"); |
4471 card_table_write(bs->byte_map_base, tmp, store_addr); |
4471 card_table_write(bs->byte_map_base, tmp, store_addr); |
4472 } |
4472 } |
4473 |
4473 |
4474 // Loading values by size and signed-ness |
4474 // Loading values by size and signed-ness |
4475 void MacroAssembler::load_sized_value(Register s1, RegisterConstant s2, Register d, |
4475 void MacroAssembler::load_sized_value(Register s1, RegisterOrConstant s2, Register d, |
4476 int size_in_bytes, bool is_signed) { |
4476 int size_in_bytes, bool is_signed) { |
4477 switch (size_in_bytes ^ (is_signed ? -1 : 0)) { |
4477 switch (size_in_bytes ^ (is_signed ? -1 : 0)) { |
4478 case ~8: // fall through: |
4478 case ~8: // fall through: |
4479 case 8: ld_long( s1, s2, d ); break; |
4479 case 8: ld_long( s1, s2, d ); break; |
4480 case ~4: ldsw( s1, s2, d ); break; |
4480 case ~4: ldsw( s1, s2, d ); break; |