Mercurial > hg > truffle
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; |