hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
changeset 2332 5c7b6f4ce0a1
parent 2256 82d4e10b7c6b
child 2347 6f161e568fe0
equal deleted inserted replaced
2259:d3c946e7f127 2332:5c7b6f4ce0a1
     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;