comparison src/cpu/sparc/vm/assembler_sparc.cpp @ 665:c89f86385056

6814659: separable cleanups and subroutines for 6655638 Summary: preparatory but separable changes for method handles Reviewed-by: kvn, never
author jrose
date Fri, 20 Mar 2009 23:19:36 -0700
parents c517646eef23
children a80d48f6fde1
comparison
equal deleted inserted replaced
647:bd441136a5ce 665:c89f86385056
1 /* 1 /*
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
2613 2613
2614 restore(); 2614 restore();
2615 } 2615 }
2616 } 2616 }
2617 2617
2618 RegisterConstant MacroAssembler::delayed_value(intptr_t* delayed_value_addr, 2618 RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
2619 Register tmp, 2619 Register tmp,
2620 int offset) { 2620 int offset) {
2621 intptr_t value = *delayed_value_addr; 2621 intptr_t value = *delayed_value_addr;
2622 if (value != 0) 2622 if (value != 0)
2623 return RegisterConstant(value + offset); 2623 return RegisterOrConstant(value + offset);
2624 2624
2625 // load indirectly to solve generation ordering problem 2625 // load indirectly to solve generation ordering problem
2626 Address a(tmp, (address) delayed_value_addr); 2626 Address a(tmp, (address) delayed_value_addr);
2627 load_ptr_contents(a, tmp); 2627 load_ptr_contents(a, tmp);
2628 2628
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) {
2803 Register temp_reg, 2803 Register temp_reg,
2804 Register temp2_reg, 2804 Register temp2_reg,
2805 Label* L_success, 2805 Label* L_success,
2806 Label* L_failure, 2806 Label* L_failure,
2807 Label* L_slow_path, 2807 Label* L_slow_path,
2808 RegisterConstant super_check_offset, 2808 RegisterOrConstant super_check_offset,
2809 Register instanceof_hack) { 2809 Register instanceof_hack) {
2810 int sc_offset = (klassOopDesc::header_size() * HeapWordSize + 2810 int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
2811 Klass::secondary_super_cache_offset_in_bytes()); 2811 Klass::secondary_super_cache_offset_in_bytes());
2812 int sco_offset = (klassOopDesc::header_size() * HeapWordSize + 2812 int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
2813 Klass::super_check_offset_offset_in_bytes()); 2813 Klass::super_check_offset_offset_in_bytes());
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;